Currently in Rust, there is no way to guarantee to the compiler that something for sure has a certain field. For example, if you are using an enum that has multiple fields, and all of those fields have the exact same name, type and purpose. I want a "semi-struct" of sorts (or maybe just a struct) that can guarantee that all variants inside of an enum have a certain field. Maybe this could also see extended use in traits or functions, to guarantee that XYZ field exists.
I have no idea how the syntax should (ideally) be structured, but here is a proposal that I have in Rust pseudocode.
The drawbacks that I see for this are in the pseudocode's comments.
// 'strict' will be important later
strict field FooField {
x: usize,
y: usize
}
field BarField {
x: usize,
y: usize
}
// The 'strict' specifier now comes into play here. Now you can automatically implement a new
// function for types that don't implement it and also have the FooField field.
trait FooTrait {
// I think the dyn keyword should be required
// for non-strict fields like BarField.
// You also shouldn't be able to initiate a type
// from Output unless it used a "strict" field.
type Output: FooField;
fn new(x: usize, y: usize) -> Output {
Output {
x,
y
}
}
}
// Implementing MULTIPLE fields on a tuple would also be problematic
// because it uses numbers to access values, as opposed to their names.
field BarTuple(x: usize, y: usize);
// Using anonymous parameters for the declaration above is probably
// just a bad idea because it makes the purpose of these values
// less clear.
enum FooEnum with FooField {
FooVariant {
// Shorthand, so you don't need to specify types.
// Also increases clarity as to which types
// come from the variant and which from the current type
// Do note that, due to the strict keyword, this doesn't compile!
x,
y,
// This throws a compiler error because 'strict' was specified. That means
// that the enum cannot contain any additional fields.
s: usize
}
// Fails, no X or Y fields
BarVariant,
NoIdeaVariant {
// Success!
x,
y
}
}
// All variants must have at least BarField's components,
// but can also add their own things
enum BarEnum with BarField {
// Valid
Pos3D {
x,
y,
z: usize
}
// Valid
Pos2D {
x, y
}
// Invalid
Pos1D {
x
}
}
As always, I greatly appreciate criticism.