diff --git a/src/hz.erl b/src/hz.erl index 9c3b202..4eb7817 100644 --- a/src/hz.erl +++ b/src/hz.erl @@ -1848,8 +1848,16 @@ coerce({O, N, string}, Str, Direction) -> StrBin -> {ok, StrBin} end; -coerce({O, N, {bytes, [Count]}}, Bytes, _Direction) when is_binary(Bytes) -> +coerce({O, N, {bytes, [Count]}}, Bytes, _Direction) when is_bitstring(Bytes) -> coerce_bytes(O, N, Count, Bytes); +coerce({_, _, bits}, {bits, Num}, from_fate) -> + {ok, Num}; +coerce({_, _, bits}, Num, to_fate) when is_integer(Num) -> + {ok, {bits, Num}}; +coerce({_, _, bits}, Bits, to_fate) when is_bitstring(Bits) -> + Size = bit_size(Bits), + <> = Bits, + {ok, {bits, IntValue}}; coerce({_, _, {list, [Type]}}, Data, Direction) when is_list(Data) -> coerce_list(Type, Data, Direction); coerce({_, _, {map, [KeyType, ValType]}}, Data, Direction) when is_map(Data) -> @@ -2524,6 +2532,14 @@ coerce_record_test() -> {ok, Type} = annotate_type({record, [{"a", integer}, {"b", integer}]}, #{}), try_coerce(Type, #{"a" => 123, "b" => 456}, {tuple, {123, 456}}). +coerce_bytes_test() -> + {ok, Type} = annotate_type({tuple, [{bytes, [4]}, {bytes, [any]}]}, #{}), + try_coerce(Type, {<<"abcd">>, <<"efghi">>}, {tuple, {<<"abcd">>, <<"efghi">>}}). + +bits_test() -> + {ok, Type} = annotate_type(bits, #{}), + try_coerce(Type, 5, {bits, 5}). + %%% Complex AACI paramter and namespace tests @@ -2610,12 +2626,27 @@ param_test() -> try_coerce(Input, 0, 0), try_coerce(Output, 0, 0). -bytes_test() -> +%%% Obscure Sophia types where we should check the AACI as well + +obscure_aaci_test() -> Contract = " contract C = - entrypoint f(): bytes(4) * bytes() = (#DEADBEEF, Bytes.to_any_size(#112233)) + entrypoint options(): option(int) = None + entrypoint fixed_bytes(): bytes(4) = #DEADBEEF + entrypoint any_bytes(): bytes() = Bytes.to_any_size(#112233) + entrypoint bits(): bits = Bits.all ", {ok, AACI} = aaci_from_string(Contract), - {ok, {[], Output}} = aaci_lookup_spec(AACI, "f"), - try_coerce(Output, {<<"abcd">>, <<"efghi">>}, {tuple, {<<"abcd">>, <<"efghi">>}}). + + IntAnnotated = {integer, already_normalized, integer}, + OptionFlat = {variant, [{"None", []}, {"Some", [IntAnnotated]}]}, + OptionAnnotated = {{option, [integer]}, already_normalized, OptionFlat}, + {ok, {[], OptionAnnotated}} = aaci_lookup_spec(AACI, "options"), + + {ok, {[], {_, _, {bytes, [4]}}}} = aaci_lookup_spec(AACI, "fixed_bytes"), + {ok, {[], {_, _, {bytes, [any]}}}} = aaci_lookup_spec(AACI, "any_bytes"), + + {ok, {[], {_, _, bits}}} = aaci_lookup_spec(AACI, "bits"), + + ok.