Ano, spravne. Jednotlive typy (XYZ) poznam uz v dobe prekladu, nevedel som spravne namodelovat Trait tak, aby som vedel "nacpat" XYZ do funkcie "push", a teda, vyuzil som mne zname std::Any.
Proč nepoužiješ enum?
Este niesom v Ruste spravne "zabehnuty" takze, neviem/netusim ako konkretne by som pouzil Enum ako nahradu za Struct ( tomto konkretnom priklade)
fn push<T:B>(&mut self, data:T)
Ano, k tomuto som sa rovnako dopracoval +- ked ste to postol.
Posielam prehladnejsi, upravenejsi kod, samozrejme v kode pouzivam Result<(), Error>, len pre prehladnost som to odstranil.
Uz sa mi to vcelku pozdava, az na nutnost DatabaseMembers, ale to si myslim, ze casom a skusenostami optimalizujem

Diky
use MYSQL::Connection;
pub enum DatabaseMembers {
X,
Y,
Z
}
// Various Structs
pub struct X {
pub name: String
}
pub struct Y {
pub text: String
}
pub struct Z {
pub value: u64
}
/* Builder - traits */
trait DatabaseBuilder {
fn push(&self, c: &Option<Connection>);
fn create_table(c: &Option<Connection>);
}
impl DatabaseBuilder for X {
fn push(&self, c: &Option<Connection>){
let query = query = "INSERT INTO x (name) VALUES (?1)"
let query_params = params![&self.name];
match c {
Some(e) => e.execute(query, query_params)?,
None => {},
};
}
fn create_table(c: &Option<Connection>){
let query =
"CREATE TABLE IF NOT EXISTS X (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
);";
match c {
Some(e) => e.execute(query, [])?,
None => {},
}
}
}
impl DatabaseBuilder for Y {
fn push(&self, c: &Option<Connection>){
let query = query = "INSERT INTO y (text) VALUES (?1)"
let query_params = params![&self.value];
match c {
Some(e) => e.execute(query, query_params)?,
None => {},
};
}
fn create_table(c: &Option<Connection>){
let query =
"CREATE TABLE IF NOT EXISTS X (
id INTEGER PRIMARY KEY,
text TEXT NOT NULL,
);";
match c {
Some(e) => e.execute(query, [])?,
None => {},
}
}
}
impl DatabaseBuilder for Z {
fn push(&self, c: &Option<Connection>){
let query = query = "INSERT INTO z (name) VALUES (?1)"
let query_params = params![&self.name];
match c {
Some(e) => e.execute(query, query_params)?,
None => {},
};
}
fn create_table(c: &Option<Connection>){
let query =
"CREATE TABLE IF NOT EXISTS X (
id INTEGER PRIMARY KEY,
name INTEGER,
);";
match c {
Some(e) => e.execute(query, [])?,
None => {},
}
}
}
impl DatabaseBuilder for Database {
fn push(&self, c: &Option<Connection>){};
fn create_table(c: &Option<Connection>){};
}
/* Database */
pub struct Database {
c: Option<Connection>,
}
impl Database {
pub fn new() -> Database {
Database {
c: None,
}
}
pub fn open_temporary(&mut self){
self.c = Some(Connection::open_in_memory());
}
pub fn push<T: DatabaseBuilder>(&mut self, data: &T) {
data.push(&self.conn)
}
pub fn create_table(&mut self, m: DatabaseMembers) {
match m {
DatabaseMembers::X => X::create_table(&self.conn),
DatabaseMembers::Y => Y::create_table(&self.conn),
DatabaseMembers::Z => Z::create_table(&self.conn),
}
}
}
fn main() {
let mut db: Database = Database::new();
db.open_temporary();
// X
db.create_table(DatabaseMembers::X);
let x = X {name: String::from("Ahoj")};
db.push(&x);
// Y
db.create_table(DatabaseMembers::Y);
let y = Y {text: String::from("Ahoj")};
db.push(&y);
}