diff --git a/src/gmser_dyn.erl b/src/gmser_dyn.erl index 1acb533..08511c4 100644 --- a/src/gmser_dyn.erl +++ b/src/gmser_dyn.erl @@ -26,6 +26,7 @@ %% register a type schema, inspect existing schema -export([ register_types/1 , registered_types/0 + , registered_types/1 , latest_vsn/0 , get_opts/1 , set_opts/1 @@ -52,50 +53,54 @@ serialize(Term) -> Vsn = latest_vsn(), - rlp_encode(encode_(Term, Vsn, registered_types(Vsn))). + rlp_encode(encode(Term, Vsn, registered_types(Vsn))). -serialize(Term, Types) -> +serialize(Term, Types0) -> + Types = proper_types(Types0), Vsn = types_vsn(Types), - rlp_encode(encode_(Term, Vsn, Types)). + rlp_encode(encode(Term, Vsn, Types)). serialize(Term, Vsn, Types) -> - rlp_encode(encode_(Term, Vsn, Types)). + rlp_encode(encode(Term, Vsn, proper_types(Types, Vsn))). serialize_typed(Type, Term) -> Vsn = latest_vsn(), - rlp_encode(encode_typed_(Type, Term, Vsn, registered_types(Vsn))). + rlp_encode(encode_typed(Type, Term, Vsn, registered_types(Vsn))). -serialize_typed(Type, Term, Types) -> +serialize_typed(Type, Term, Types0) -> + Types = proper_types(Types0), Vsn = types_vsn(Types), - rlp_encode(encode_typed_(Type, Term, Vsn, Types)). + rlp_encode(encode_typed(Type, Term, Vsn, Types)). serialize_typed(Type, Term, Vsn, Types) -> - rlp_encode(encode_typed_(Type, Term, Vsn, Types)). + rlp_encode(encode_typed(Type, Term, Vsn, proper_types(Types, Vsn))). deserialize(Binary) -> Fields0 = rlp_decode(Binary), case decode_tag_and_vsn(Fields0) of {0, Vsn, Fields} -> - decode(Fields, Vsn, registered_types(Vsn)); + decode_(Fields, Vsn, registered_types(Vsn)); Other -> error({illegal_serialization, Other}) end. -deserialize(Binary, Types) -> - Vsn0 = maps:get(vsn, Types, undefined), +deserialize(Binary, Types0) -> + Types = proper_types(Types0), + Vsn0 = types_vsn(Types), Fields0 = rlp_decode(Binary), case decode_tag_and_vsn(Fields0) of {0, Vsn, Fields} when Vsn0 == undefined; Vsn0 == Vsn -> - decode(Fields, Vsn, Types); + decode_(Fields, Vsn, Types); Other -> error({illegal_serialization, Other}) end. -deserialize(Binary, Vsn, Types) -> +deserialize(Binary, Vsn, Types0) -> + Types = proper_types(Types0), Fields0 = rlp_decode(Binary), case decode_tag_and_vsn(Fields0) of {0, Vsn, Fields} -> - decode(Fields, Vsn, Types); + decode_(Fields, Vsn, Types); Other -> error({illegal_serialization, Other}) end. @@ -104,11 +109,12 @@ encode(Term) -> Vsn = latest_vsn(), encode(Term, Vsn, registered_types(Vsn)). -encode(Term, Types) -> +encode(Term, Types0) -> + Types = proper_types(Types0), encode(Term, types_vsn(Types), Types). encode(Term, Vsn, Types0) -> - Types = assert_vsn(Vsn, Types0), + Types = proper_types(Types0, Vsn), [ encode_basic(int, 0) , encode_basic(int, Vsn) , encode_(Term, Vsn, Types) ]. @@ -117,11 +123,12 @@ encode_typed(Type, Term) -> Vsn = latest_vsn(), encode_typed(Type, Term, Vsn, registered_types(Vsn)). -encode_typed(Type, Term, Types) -> +encode_typed(Type, Term, Types0) -> + Types = proper_types(Types0), encode_typed(Type, Term, types_vsn(Types), Types). encode_typed(Type, Term, Vsn, Types0) -> - Types = assert_vsn(Vsn, Types0), + Types = proper_types(Types0, Vsn), [ encode_basic(int, 0) , encode_basic(int, Vsn) , encode_typed_(Type, Term, Vsn, Types) ]. @@ -130,11 +137,12 @@ decode(Fields) -> Vsn = latest_vsn(), decode(Fields, Vsn, registered_types(Vsn)). -decode(Fields, Types) -> +decode(Fields, Types0) -> + Types = proper_types(Types0), decode(Fields, types_vsn(Types), Types). decode(Fields0, Vsn, Types0) -> - Types = assert_vsn(Vsn, Types0), + Types = proper_types(Types0, Vsn), case decode_tag_and_vsn(Fields0) of {0, Vsn, Fields} -> decode_(Fields, Vsn, Types); @@ -146,11 +154,12 @@ decode_typed(Type, Fields) -> Vsn = latest_vsn(), decode_typed(Type, Fields, Vsn, registered_types(Vsn)). -decode_typed(Type, Fields, Types) -> +decode_typed(Type, Fields, Types0) -> + Types = proper_types(Types0), decode_typed(Type, Fields, types_vsn(Types), Types). decode_typed(Type, Fields0, Vsn, Types0) -> - Types = assert_vsn(Vsn, Types0), + Types = proper_types(Types0, Vsn), case decode_tag_and_vsn(Fields0) of {0, Vsn, Fields} -> decode_from_template(Type, Fields, Vsn, Types); @@ -163,6 +172,16 @@ decode_tag_and_vsn([TagBin, VsnBin, Fields]) -> decode_basic(int, VsnBin), Fields}. +proper_types(undefined) -> + registered_types(latest_vsn()); +proper_types(#{} = Types) -> + Types. + +proper_types(undefined, Vsn) -> + registered_types(Vsn); +proper_types(#{} = Types, Vsn) -> + assert_vsn(Vsn, Types). + types_vsn(#{vsn := Vsn}) -> Vsn; types_vsn(_) -> latest_vsn(). @@ -768,6 +787,11 @@ round_trip_test_() -> T <- t_sample_types() ]. +ser_round_trip_test_() -> + [?_test(t_ser_round_trip(T)) || + T <- t_sample_types() + ]. + t_sample_types() -> [ 5 , -5 @@ -813,6 +837,11 @@ t_round_trip(T) -> ?debugVal(T), ?assertMatch({T, T}, {T, decode(encode(T))}). +t_ser_round_trip(T) -> + Data = serialize(T), + ?debugFmt("Data (~p) = ~p~n", [T, Data]), + ?assertMatch({T, T}, {T, deserialize(Data)}). + t_round_trip_typed(Type, T) -> ?debugVal(T), ?assertMatch({T, T}, {T, decode(encode_typed(Type, T))}).