-
Notifications
You must be signed in to change notification settings - Fork 240
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
Implement record type #243
Conversation
@@ -2,6 +2,7 @@ namespace rondpoint { | |||
Dictionnaire copie_dictionnaire(Dictionnaire d); | |||
Enumeration copie_enumeration(Enumeration e); | |||
sequence<Enumeration> copie_enumerations(sequence<Enumeration> e); | |||
record<DOMString, Enumeration> copie_carte(record<DOMString, Enumeration> c); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- IDL record type is limited: the key has to be a string type, however the value can be anything.
- weedle will not parse
string
, so you have to declare aDOMString
instead (it still maps properly to a rustString
, we actually ignore the Key type).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is an okay start, and we can figure out other key types as we go. Kinda surprised weedle
wouldn't parse string
, but oh well.
Type::Map(t) => format!( | ||
"lowerMap({}, {{ k, v -> {} + {} }}, {{ k, v, buf -> {}; {} }})", | ||
nm, | ||
calculate_write_size(&"k", &Type::String)?, | ||
calculate_write_size(&"v", t)?, | ||
write_kt(&"k", &"buf", &Type::String)?, | ||
write_kt(&"v", &"buf", t)? | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤮
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol, but also, I wonder if something similar to what I tried for python over in #214 could be slightly less vomit-inducing here; thoughts? (for a future PR of course, not this one)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'm concerned about is that we would generate a lot of extra code for each new record/sequence/etc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I guess it's similar to the use of monomorphization in rust, where you end up generating lots of almost-duplicate code. (I don't think it would balloon too badly in practice, because you'd only get one method per type-you-actually-use-in-a-sequence, not one for every single type. But, worth watching out for).
@@ -97,7 +97,13 @@ mod filters { | |||
Type::Enum(type_name) => format!("{} = {}({})", nm, type_name, nm), | |||
Type::Record(type_name) => format!("{} = {}._coerce({})", nm, type_name, nm), | |||
Type::Optional(t) => format!("(None if {} is None else {})", nm, coerce_py(nm, t)?), | |||
Type::Sequence(t) => format!("({} for x in {})", coerce_py(&"x", t)?, nm), // TODO: name hygiene | |||
Type::Sequence(t) => format!("({} for x in {})", coerce_py(&"x", t)?, nm), // TODO: name hygiene, | |||
Type::Map(t) => format!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't finish the python implementation, I think the other PR needs to land first.
associatedtype Value | ||
static func lift(_ v: Value) throws -> Self | ||
func lower() -> Value | ||
associatedtype FfiType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unfortunate, but in the extension Dictionary
below the Swift compiler couldn't disambiguate between ViaFfi.Value
and Dictionary.Value
in the where
declaration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I would support renaming this to FfiType
or LoweredType
or similar on the rust side as well, I think it more clearly communicates the intent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, I do think we'll probably have to eventually add different key types (at least number types), but we can figure that out later if this helps us get our demos unblocked (👀 on the fxa_client)
@@ -2,6 +2,7 @@ namespace rondpoint { | |||
Dictionnaire copie_dictionnaire(Dictionnaire d); | |||
Enumeration copie_enumeration(Enumeration e); | |||
sequence<Enumeration> copie_enumerations(sequence<Enumeration> e); | |||
record<DOMString, Enumeration> copie_carte(record<DOMString, Enumeration> c); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is an okay start, and we can figure out other key types as we go. Kinda surprised weedle
wouldn't parse string
, but oh well.
uniffi/src/lib.rs
Outdated
fn write<B: BufMut>(&self, buf: &mut B) { | ||
// TODO: would be nice not to panic here :-/ | ||
let len = u32::try_from(self.len()).unwrap(); | ||
buf.put_u32(len); // We limit HashMaps to u32::MAX bytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
buf.put_u32(len); // We limit HashMaps to u32::MAX bytes | |
buf.put_u32(len); // We limit HashMaps to u32::MAX items |
uniffi/src/lib.rs
Outdated
/// the key must always be of the String type. | ||
/// | ||
/// HashMaps are currently always passed by serializing to a bytebuffer. | ||
/// We write a `u32` entries count followed by each entry in turn. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: please document that an "entry" is the string key followed by the value.
|
||
fun<V> readMap(buf: ByteBuffer, readItem: (ByteBuffer) -> Pair<String, V>): Map<String, V> { | ||
val len = Int.read(buf) | ||
@OptIn(ExperimentalStdlibApi::class) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What effect will this opting-in to experiment stuff have on our consumers, if any?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should result in a warning during compilation, if we find this unacceptable we can always switch to a more stable construct.
associatedtype Value | ||
static func lift(_ v: Value) throws -> Self | ||
func lower() -> Value | ||
associatedtype FfiType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I would support renaming this to FfiType
or LoweredType
or similar on the rust side as well, I think it more clearly communicates the intent.
7a45fb2
to
c21480d
Compare
525b8a8
to
759ce67
Compare
Oh, that is very slick, thankyou github! |
Fixes #226.
There's some awkwardness in here, but it's not a shower-stopper imo.