-
Notifications
You must be signed in to change notification settings - Fork 218
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
Confusion with structure member optionality in IDL v2 in clients #1478
Comments
I think this is something you need to answer yourself when building a generator. It sounds like more of a general question on how to use default values with a struct in Rust. I know in languages with constructors, builders, etc, you have an opportunity to set defaults when they aren't provided.
I think you're inferring that because it requires a value in the example Rust type, then all inputs should have optional members for anything that has a default value so that caller doesn't have to set the default themselves. I think that's the same question as above though. Plenty of types are shared between inputs and outputs though, and it doesn't seem easy to manage for a team modeling their service because you can at any time go from referencing a shape only in input to referencing it in both input and output. |
Yeah that's fair. I think I'm now inclined to keep the spec as-is in this regard, because changing the type of a struct member when it ceases to be transitively reachable in operation input is likely to cause confusion, whereas adding/removing
Yes, in Rust we will use builders to enact the benefits of let foo = Foo::builder().build();
let foo2 = Foo::builder().bar("hello").build();
let foo3 = Foo {
bar: String::from("hello"),
}
assert_eq!(foo, foo2);
assert_eq!(foo2, foo3); |
I think all that remains to be cleared up is whether adding and removing // Works, same code with same semantics.
let foo = Foo::builder().build();
// Still works because the builder method for `.bar()` wraps `"hello"` in `Some`
// in its implementation.
let foo2 = Foo::builder().bar("hello").build();
// Breaking change.
let foo2 = Foo {
bar: Some(String::from("hello")),
} You get a similar situation when considering an example where you remove I don't see a way to mitigate this breakage by modifying the spec, so this most likely should be addressed in the Rust code generator. I don't know how though; perhaps @rcoh has some trick up his sleeve. |
Yeah, adding the |
The spec says that a client (i.e. a non-authoritative model consumer) should render a structure member shape with
@default
as:My reading of that is that the
bar
member of theFoo
structure in this model:should be rendered in Rust as not optional, i.e. a plain
std::string::String
:But I don't see the purpose of
@default
in this particular example then. The user still has to always provide a value forbar
.Should the phrase be reworded to "Present unless also
@clientOptional
or reachable via an operation's input"?Note that adding
@input
is not listed as a backwards incompatible change, so it feels odd that@input
appears in that table: if I were to add@input
to theFoo
structure shape in the model above, the spec would dictate thatbar
be of typeOption<T>
then, and that is backwards incompatible in Rust.The text was updated successfully, but these errors were encountered: