Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contract Spec: Define how to encode user defined Rust structs into RawVal objs #24

Closed
leighmcculloch opened this issue Apr 15, 2022 · 6 comments · Fixed by #140
Closed
Assignees

Comments

@leighmcculloch
Copy link
Member

No description provided.

@leighmcculloch leighmcculloch added this to the v0 milestone Apr 15, 2022
@leighmcculloch
Copy link
Member Author

leighmcculloch commented Apr 15, 2022

@jonjove suggested implementing serde so that a struct with fields would be serialized to a Val Vec obj handle where each field is mapped to an index.

@leighmcculloch leighmcculloch changed the title Figure out how to encode Rust structs into Val maps Figure out how to encode user defined Rust structs into Val objs Apr 15, 2022
@jonjove
Copy link
Contributor

jonjove commented Apr 15, 2022

Not necessarily serde specifically, but at least something quite like it.

@leighmcculloch leighmcculloch self-assigned this May 20, 2022
@leighmcculloch leighmcculloch removed their assignment Jun 3, 2022
@leighmcculloch leighmcculloch changed the title Figure out how to encode user defined Rust structs into Val objs Define how to encode user defined Rust structs into RawVal objs Jun 3, 2022
@leighmcculloch
Copy link
Member Author

Note to self to look at CAP-54 that demonstrates one way to do this, using SCO_VEC's to both encode enums and types: stellar/stellar-protocol#1224. This is a pattern we've discussed a few times in different contexts, but CAP-54 is the first CAP or SEP that concretely demonstrates the pattern in use.

@leighmcculloch
Copy link
Member Author

leighmcculloch commented Jun 22, 2022

@jonjove found a good way to encode enums/unions using a tuple and a EnvVal tail, that will probably work pretty well. There's little need to make enums a map and so they could be implemented as a tuple/vec like this.

122 pub enum KeyedAuthorization {
123     Contract,
124     Ed25519(KeyedEd25519Authorization),
125     Account(KeyedAccountAuthorization),
126 }
127
128 impl TryFrom<EnvVal> for KeyedAuthorization {
129     type Error = ();
130
131     #[inline(always)]
132     fn try_from(ev: EnvVal) -> Result<Self, Self::Error> {
133         let (discriminant, tail): (u32, EnvVal) = ev.try_into()?;
134         match discriminant {
135             0 => Ok(KeyedAuthorization::Contract),
136             1 => Ok(KeyedAuthorization::Ed25519(tail.try_into()?)),
137             2 => Ok(KeyedAuthorization::Account(tail.try_into()?)),
138             _ => Err(()),
139         }
140     }
141 }
142
143 impl IntoEnvVal<Env, RawVal> for KeyedAuthorization {
144     #[inline(always)]
145     fn into_env_val(self, env: &Env) -> EnvVal {
146         match self {
147             KeyedAuthorization::Contract => (0u32, ()).into_env_val(env),
148             KeyedAuthorization::Ed25519(kea) => (1u32, kea).into_env_val(env), ‣KeyedEd25519Authorization
149             KeyedAuthorization::Account(kaa) => (2u32, kaa).into_env_val(env), ‣KeyedAccountAuthorization
150         }
151     }
152 }

We could probably do some work to make enums that have unit values more concise.

@leighmcculloch leighmcculloch self-assigned this Jun 24, 2022
@leighmcculloch leighmcculloch linked a pull request Jun 24, 2022 that will close this issue
@leighmcculloch leighmcculloch changed the title Define how to encode user defined Rust structs into RawVal objs Contract Spec: Define how to encode user defined Rust structs into RawVal objs Jul 6, 2022
@leighmcculloch leighmcculloch mentioned this issue Jul 6, 2022
12 tasks
@tomerweller tomerweller removed this from the v0 milestone Jul 8, 2022
@leighmcculloch
Copy link
Member Author

leighmcculloch commented Jul 11, 2022

UDT mappings to host types:

Struct

Structs use the Host Map as their underlying structure. There is a single item in the map for each field of the struct. The struct field name is the key and its value is the value. This is implemented, although there are plenty of TODOs.

Union (Rust enums where the values are not integers)

Unions use the Host Vec as their underlying structure. The Union is a two element Vec, where the first element is the name of the variant, and the second is the value of the variant. Unit type variants are stored as a void. This is implemented, although there are plenty of TODOs, and the discriminant is currently implemented as an integer index, but will be changed to be a symbol.

Enums (Rust enums where the values are integers)

Enums merely use the primitive integer type of their representation. This is not yet implemented.


Note that in all there is no storing of the type name, etc, and they are rendered purely as their structural components.

cc @graydon @jonjove

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants