Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::rc::Rc;
- // We have two simple models in our database:
- struct Question {
- id: u64,
- body: String
- }
- struct Answer {
- id: u64,
- question_id: u64,
- body: String,
- }
- // Our Database object holds an (imaginary) connection to a database server.
- // We want to use that same connection for all database requests in our program.
- struct Database {
- connection: (),
- }
- // So when we create an instance of the Database, we return it in an Rc
- // reference-counted smart pointer, so everything that needs it can refer to
- // that same connection.
- impl Database {
- pub fn connect(_server: String) -> Rc<Self> {
- Rc::new(Self { connection: () })
- }
- // When we return results, we give them a new reference by cloning self
- // (Rc<Self>), incrementing the count.
- pub fn get_question(self: Rc<Self>, id: u64) -> LinkedQuestion {
- LinkedQuestion {
- database: self.clone(),
- question: self.get_question_without_wrapper(id),
- }
- }
- // Note that if we just need to refer to the Database, but don't need to
- // create a new Rc reference, we can just use &self instead.
- pub fn get_question_without_wrapper(&self, id: u64) -> Question {
- unimplemented!("TODO: get it from self.connection")
- }
- }
- // We use this to create model wrappers that can resolve foreign references.
- struct LinkedAnswer {
- db: Rc<Database>,
- answer: Answer,
- }
- struct LinkedQuestion {
- db: Rc<Database>,
- question: Question,
- }
- impl LinkedAnswer {
- fn get_question(&self) -> LinkedQuestion {
- // However, note that when we're calling methods on the database through
- // an Rc<>, we need to .clone() the reference first to make sure we
- // have a new Rc reference to pass in as `self`. Not horrible, but
- // noisy and a little unclear.
- self.db.clone().get_question(self.answer.question_id);
- }
- }
- #![feature(arbitrary_self_types)]
- impl Database {
- // By enabling the nightly-only "arbitrary_self_types" feature flag, we can
- // modify so that we only take a & reference to the Rc<>, instead of taking
- // ownership of it. This way, the caller won't need to clone it, but we can
- // still clone it (because clone just requires a & reference) if we need to
- // create a new reference!
- pub fn get_question(self: &Rc<Self>, id: u64) -> LinkedQuestion {
- LinkedQuestion {
- database: self.clone(),
- question: self.get_question_without_wrapper(id),
- }
- }
- }
- impl LinkedAnswer {
- fn get_question(&self) -> LinkedQuestion {
- // No clone!
- self.db.get_question(self.answer.question_id);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement