Majme nasledujuci kod, kde mame strukturu X, Y, Z a majme "Database" ktora obsahuje funkciu "push" - vstup je "Any". Na zaklade typu vstupujuceho do "push" sa rozhodne ktory template sa zavola.
Dany zapis samozrejme funguje, len to nieje to prave orechove, skusenejsi kolegovia, mate nejaky navrh na zlepsenie?
// Various Structs
pub struct X {
name: String
}
pub struct Y {
text: String
}
pub struct Z {
value: u64
}
/* Builder - traits */
trait DatabaseBuilder<T> {
fn add(&self, data: &T);
}
impl DatabaseBuilder<X> for Database {
fn push(&self, data: &X){
/* ... */
let y = data.name;
}
}
impl DatabaseBuilder<Y> for Database {
fn push(&self, data: &Y){
/* ... */
let y = data.text;
}
}
impl DatabaseBuilder<Z> for Database {
fn push(&self, data: &Z){
/* ... */
let y = data.value;
}
}
/* Database */
pub struct Database {
/* ... */
}
impl Database {
pub fn new() -> Databse {
/* ... */
}
pub fn push(&mut self, data: &dyn std::any::Any) {
match data.downcast_ref::<X>() {
Some(p) => DatabaseBuilder::<X>::push(self, p),
None => {}
}
match data.downcast_ref::<Y>() {
Some(p) => DatabaseBuilder::<Y>::push(self, p),
None => {}
}
match data.downcast_ref::<Z>() {
Some(p) => DatabaseBuilder::<Z>::push(self, p),
None => {}
}
}
}