Replace Or Supplement std::type_name with std::struct_tag #966
Description
So currently if you want to do type introspection, you use the std::type_name::get() function to get a TypeName, then convert it into a string, and then parse that string to the type-name up into one of its component pieces (i.e., package-id or module-name). We've written a bunch of utility functions that do this parsing:
https://github.com/capsule-craft/capsules/blob/master/packages/sui_utils/sources/encode.move
However, what would be simpler and more useful would be to skip strings altogether, and simply return StructTags, like this:
struct StructTag has store, copy, drop {
package_id: address,
module_name: string::String,
struct_name: string::String,
generics: vector<string::String>
}
Note that it might have been interesting to make make struct_tag.generics be of type vector instead, but this sort of recursive type definition is not allowed, so the generics will just have to be strings.
For Sui Move, it might be interesting to have package_id be a sui::object::ID instead of an address, but for the Move core IDs do not exist.
We've implemented StructTags here:
https://github.com/capsule-craft/capsules/blob/master/packages/sui_utils/sources/struct_tag.move
Currently these are created using string-parsing, but if StructTags were created natively within Move it would presumably be a lot cheaper to construct them than having to parse ascii strings. These StructTags can be used to compare object-types rather easily; i.e., are they from the same package, the same module, are they the same struct but with different generics, etc.
In addition to being faster and simpler to work with, than TypeNames StructTags are also smaller to store. Addresses are encoded as hex in ascii, meaning that a 32 byte address uses up 64 bytes of storage as a hex-ascii string. I honestly can't really think of any downsides.
As an edge-case, for primitive types like address
, bool
, or u64
, we could return this:
StructTag {
package_id: 0x0,
module_name: "",
struct_name: "u64",
generics: [ ]
}
Or we could make package_id be optional and just leave it empty in this case.