Module tag.
Inductive t :=
| Null : t
| Bool : bool -> t
| Num : nat -> t
| Str : String.string -> t
| Arr : t
| Obj : t.
(* tag serializer *)
Definition tag_serialize (t : t) : IOStreamWriter.t :=
match t with
| Null => serialize x00
| Bool b => IOStreamWriter.append (fun _ => serialize x01)
(fun _ => serialize b)
| Num n => IOStreamWriter.append (fun _ => serialize x02)
(fun _ => serialize n)
| Str s => IOStreamWriter.append (fun _ => serialize x03)
(fun _ => serialize s)
| Arr => serialize x04
| Obj => serialize x05
end.
Definition tag_deserialize : ByteListReader.t t :=
tag <- deserialize ;;
match tag with
| x00 => ByteListReader.ret Null
| x01 => Bool <$> deserialize
| x02 => Num <$> deserialize
| x03 => Str <$> deserialize
| x04 => ByteListReader.ret Arr
| x05 => ByteListReader.ret Obj
| _ => ByteListReader.error
end.

Lemma tag_serialize_deserialize_id :
serialize_deserialize_id_spec tag_serialize tag_deserialize.