Hello,
I wanted to not have to repeat the type of a temporary struct that I pass to a function.
let s = S;
// this works but is unnecessary verbose
s.foo(DataForS{x: 1, y: 2});
// this doesn't compiles
s.foo({x: 1, y: 2});
The syntax I used is what you can do in C++. AFAIK it's not possible at all in Rust to use/emulate it, but I wanted to be sure.
My real use-case is that I am creating a trait, and I want to be able to pass custom data to one of the functions of that trait. The type of that custom data will change for every implementation of the trait and will only ever be used for that function. I'm happy with everything but the verbosity of the call site, since it's redundant to have to specify the type of the data passed to this function (that information is already visible with the type of the object implementing the trait).
I wasn't able to get this working for methods, but for free functions - that's the idea: to call the function through the macro, which, in turn, can be auto-generated by another macro. This is not very pretty, but if you're interested, that's what I'd dug into.
In nightly (with const_generics), there is a way to express the "structure" of a struct within the type / trait system, making it possible to define a genericity over "structs with (at least) the same fields", at which point one can create a dummy struct with the given fields. And all that can be wrapped using macros:
#[derive(Debug)]
struct Person {
name: String,
age: u8,
}
/// Imagine this is generated by a derive macro:
const _: () = {
impl<T> IntoStruct<Person> for T
where
T : Sized
+ TakeField<"name", T = String>
+ TakeField<"age", T = u8>
{
fn into_struct (mut self: Self) -> Person
{
Person {
name: TakeField::<"name">::take(&mut self),
age: TakeField::<"age">::take(&mut self),
}
}
}
};
#[derive(Debug)]
struct Animal {
name: String,
age: u8,
}
/// Ditto
impl<T> IntoStruct<Animal> for T where T : ...
fn foo_person (p: Person)
{
dbg!(p);
}
fn foo_animal (p: Animal)
{
dbg!(p);
}
fn main ()
{
foo_person(S! {
name: "John!".into(),
age: 42,
});
foo_animal(S! {
name: "Laika".into(),
age: 6,
});
}
FWIW, it seems to be possible to express this const _: &'static str type-level genericity over the fields names without const_generics, by expressing strings directly at the type level, which the ::structural crate seems to achieve.