Feature to change generic field upon invoking setters method of generic type
Swoorup opened this issue · 3 comments
Is it possible to add functionality which changes the generic parameter of the struct?
For example,
#[derive(Default, Setters, Debug, PartialEq, Eq)]
struct GenericStruct<'a, A, B, C> {
a: Option<&'a A>,
b: Option<&'a B>,
c: C,
}
let a = GenericStruct::default().a(Some(&30)).b(Some(&10)).c(20); // `GenericStruct<i32, i32, 32>`
let b = a.b(Some("Hello")); // Now the type is `GenericStruct<i32, str, i32>`
This would not be possible for the given struct, but would be possible for structs in which each generic parameter is used for only one field. Given that limitation, it would be possible, but I'm not sure it'd be particularly worth implementing then.
At this line:
let b = a.b(Some("Hello")); // Now the type is `GenericStruct<str>`
This function would be impossible to implement, as there is no way to initialize b.a
and b.c
based on a
, as they have an i32
for T
instead of str
.
Apologies, my example was bad (Fixed it). Yeah currently just need one field generic parameter to be mutated to a different type.
I encounter this often when writing event sourcing apps, i.e I want to process an event and perhaps convert it to a different type but retain the metadata information.
#[derive(Serialize, Deserialize, Clone)]
struct EventMetadata {
correlation_id: Uuid,
customer_id: Uuid,
}
#[derive(Serialize, Deserialize)]
struct Event<T> {
metadata: EventMetadata,
payload: T,
}
// Example payloads
#[derive(Serialize, Deserialize)]
struct OrderCreated {
order_id: String,
customer_id: String,
}
#[derive(Serialize, Deserialize)]
struct OrderProcessed {
order_id: String,
status: String,
}
fn process_order(created: Event<OrderCreated>) -> Event<OrderProcessed> {
....
Event {
metadata: created.metadata.clone(),
payload,
}
}
I do also use an algebraic data type for the Event, but sometimes I want to pass a narrowed Event to functions that don't necessarily need to handle all Event enum cases, but also neeed the metadata along as well.