Advertisement
Guest User

Untitled

a guest
May 20th, 2019
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.62 KB | None | 0 0
  1. use std::rc::Rc;
  2.  
  3. // We have two simple models in our database:
  4.  
  5. struct Question {
  6. id: u64,
  7. body: String
  8. }
  9.  
  10. struct Answer {
  11. id: u64,
  12. question_id: u64,
  13. body: String,
  14. }
  15.  
  16. // Our Database object holds an (imaginary) connection to a database server.
  17. // We want to use that same connection for all database requests in our program.
  18.  
  19. struct Database {
  20. connection: (),
  21. }
  22.  
  23. // So when we create an instance of the Database, we return it in an Rc
  24. // reference-counted smart pointer, so everything that needs it can refer to
  25. // that same connection.
  26.  
  27. impl Database {
  28. pub fn connect(_server: String) -> Rc<Self> {
  29. Rc::new(Self { connection: () })
  30. }
  31.  
  32. // When we return results, we give them a new reference by cloning self
  33. // (Rc<Self>), incrementing the count.
  34. pub fn get_question(self: Rc<Self>, id: u64) -> LinkedQuestion {
  35. LinkedQuestion {
  36. database: self.clone(),
  37. question: self.get_question_without_wrapper(id),
  38. }
  39. }
  40.  
  41. // Note that if we just need to refer to the Database, but don't need to
  42. // create a new Rc reference, we can just use &self instead.
  43. pub fn get_question_without_wrapper(&self, id: u64) -> Question {
  44. unimplemented!("TODO: get it from self.connection")
  45. }
  46. }
  47.  
  48. // We use this to create model wrappers that can resolve foreign references.
  49. struct LinkedAnswer {
  50. db: Rc<Database>,
  51. answer: Answer,
  52. }
  53.  
  54. struct LinkedQuestion {
  55. db: Rc<Database>,
  56. question: Question,
  57. }
  58.  
  59. impl LinkedAnswer {
  60. fn get_question(&self) -> LinkedQuestion {
  61. // However, note that when we're calling methods on the database through
  62. // an Rc<>, we need to .clone() the reference first to make sure we
  63. // have a new Rc reference to pass in as `self`. Not horrible, but
  64. // noisy and a little unclear.
  65. self.db.clone().get_question(self.answer.question_id);
  66. }
  67. }
  68.  
  69.  
  70. #![feature(arbitrary_self_types)]
  71. impl Database {
  72. // By enabling the nightly-only "arbitrary_self_types" feature flag, we can
  73. // modify so that we only take a & reference to the Rc<>, instead of taking
  74. // ownership of it. This way, the caller won't need to clone it, but we can
  75. // still clone it (because clone just requires a & reference) if we need to
  76. // create a new reference!
  77. pub fn get_question(self: &Rc<Self>, id: u64) -> LinkedQuestion {
  78. LinkedQuestion {
  79. database: self.clone(),
  80. question: self.get_question_without_wrapper(id),
  81. }
  82. }
  83. }
  84.  
  85. impl LinkedAnswer {
  86. fn get_question(&self) -> LinkedQuestion {
  87. // No clone!
  88. self.db.get_question(self.answer.question_id);
  89. }
  90. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement