parse_tx_info takes the output of tx_info OR dry_run and strips it down to a cb_ encoded binary,
and then passes that cb_ encoded binary to decode_bytearray, using the Format specified.
read_contract_getter combines contract_call and dry_run, but automatically identifies the owner of the contract,
and uses that as the caller, and gives the caller a huge amount of gajus for the purpose of the dry run, so that
the call always succeeds. This operation should be available in the node itself, rather than requiring us to do
this huge back and forth for something as simple as reading the contents of the blockchain, but at least we can
abstract over this in the tooling, and save the user from having to think about these steps.
fate_to_erlang can only really fail at runtime if the wrong AACI is
provided, in which case the details of how failure occured are not
helpful, or recoverable. Anything else will be so broken that dialyzer
will catch it, or is a bug in hakuzaru, that we want to know about.
This is outside of the scope of the sophia parser, but is a simple generalization to
'sophia terms' to make them able to represent any FATE term anonymously.
We also parse these anonymous variant expressions without type info, since it is convenient
for users to copy the output of one call into another call.
Anonymous parsing of None and Some was also added, since new users would be shocked if this
doesn't work, and advanced users will greatly appreciate that it does. The resulting FATE
terms are still rendered as variant([0, 1], ...), since user defined types can also have [0, 1]
as their arity list, and since automation and tooling programmers hate special case exceptions like that.
Anonymous parsing of other Chain and AENS terms are not added, since anonymous variants already cover those types,
so very little is gained by hard-coding such complex types into the term parser. Complex, version-specific compiler
types are already supported by hakuzaru, in the form of the ACI/AACI; parsing without AACI, on the other hand, is
intended to support language-agnostic communication using the primitives of FATE, and in general, variants
in FATE are anonymous.
This one was much simpler to do than hz_aaci, since it doesn't introduce any new types.
I could have made note of some of the conventions, where a type can be represented in multiple
ways in Sophia syntax, or where these functions are actually more lenient than the compiler, but
it isn't as easy to break those notes up from the basic function usage, like it was in hz_aaci,
where those aforementioned new types are used.
A while ago I tried dialyzer and discovered that actually a lot of the AACI generation process
never fails, and whatever the one failure was that was possible, I think I decided was unnecessary,
and made that produce {ok, unknown_type} instead. I then set the types of these functions to be
{ok, Result} | {error, none()}, since there were in fact no errors, but dialyzer still spewed out
warnings for all the case blocks that redundantly check for these impossible error conditions.
Anyway now that is fixed! The behavior and external interface are all the same still, there are just fewer warnings
now.
Also added specs for a couple more internal functions, just because.
So noperhaps realized that actually none of it should fail. I never went in and
removed all the {ok, _} wrappers, but I did at least type the functions with the correct error list
I changed it from noting the index to just noting the field name, but
actually both pieces of information are important, since if there was
a type error, presumably the type information is actually wrong.
Now we put the index first, since that is the part of the FATE tuple
that failed, and then the field name that that would be if the type
information were correct, in case that is useful.
This warning always confuses me. Usually it is a case I haven't actually implemented,
but I don't need the program to diagnose that for me, I need the program to tell me what the
type was, so that I can work out why it thinks it isn't implemented.
All three terms of the annotated type are relevant, but the annotated version can only differ from the normalized version if
it is a record or variant definition, so we special case those two just to communicate that the fact that it is *some* kind of record
did successfully pass through to the coerce logic, and otherwise we just try and print the opaque and normalized types faithfully.
I realized this case needed special handling in hz_sophia, but didn't
get around to covering it properly in the older hz_aaci analogues.
While I was at it, I went and improved the error paths for record elements.