Created
July 17, 2020 09:55
Change implementation of trait object using RefCell<Rc<dyn Obj>>
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::rc::Rc; | |
use std::cell::RefCell; | |
// Databases | |
trait DB { | |
fn find(&self) -> String; | |
} | |
struct SQL; | |
impl DB for SQL { | |
fn find(&self) -> String { | |
"SQL".to_owned() | |
} | |
} | |
struct Mongo; | |
impl DB for Mongo { | |
fn find(&self) -> String { | |
"Mongo".to_owned() | |
} | |
} | |
// Services | |
trait Executor { | |
fn execute(&self); | |
} | |
struct Serv1 { | |
db: RefCell<Rc<dyn DB>>, | |
} | |
impl Serv1 { | |
fn change_db(&self, db: Rc<dyn DB>) { | |
*self.db.borrow_mut() = db; | |
} | |
} | |
impl Executor for Serv1 { | |
fn execute(&self) { | |
println!("Serv1: {}", self.db.borrow().find()); | |
} | |
} | |
struct Serv2 { | |
db: Rc<dyn DB>, | |
serv1: Rc<Serv1>, | |
} | |
impl Executor for Serv2 { | |
fn execute(&self) { | |
println!("Serv2: {}", self.db.find()); | |
self.serv1.execute(); | |
} | |
} | |
struct Serv3 { | |
db: Rc<dyn DB>, | |
serv1: Rc<Serv1>, | |
serv2: Rc<Serv2>, | |
} | |
impl Executor for Serv3 { | |
fn execute(&self) { | |
println!("Serv3: {}", self.db.find()); | |
self.serv1.execute(); | |
self.serv2.execute(); | |
} | |
} | |
fn main() { | |
let mongo: Rc<dyn DB> = Rc::new(Mongo); | |
let sql: Rc<dyn DB> = Rc::new(SQL); | |
let mut serv1 = Rc::new(Serv1 { | |
db: RefCell::new(Rc::clone(&sql)), | |
}); | |
let serv2 = Rc::new(Serv2 { | |
db: Rc::clone(&mongo), | |
serv1: Rc::clone(&serv1), | |
}); | |
let serv3 = Rc::new(Serv3 { | |
db: Rc::clone(&sql), | |
serv1: Rc::clone(&serv1), | |
serv2: Rc::clone(&serv2), | |
}); | |
println!("#sql: {} | #mongo: {}", Rc::strong_count(&sql), Rc::strong_count(&mongo)); | |
serv3.execute(); | |
serv1.change_db(Rc::clone(&mongo)); | |
println!("---"); | |
println!("#sql: {} | #mongo: {}", Rc::strong_count(&sql), Rc::strong_count(&mongo)); | |
serv3.execute(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment