From ce86d252e529385704fe9111e305ac0ec48c2de4 Mon Sep 17 00:00:00 2001
From: Denton24646 <Denton24646@gmail.com>
Date: Sat, 16 Jul 2022 15:31:37 -0400
Subject: [PATCH] feat: add rc1.rs exercise

---
 exercises/standard_library_types/rc1.rs | 98 +++++++++++++++++++++++++
 info.toml                               | 14 ++++
 2 files changed, 112 insertions(+)
 create mode 100644 exercises/standard_library_types/rc1.rs

diff --git a/exercises/standard_library_types/rc1.rs b/exercises/standard_library_types/rc1.rs
new file mode 100644
index 00000000..9b907fde
--- /dev/null
+++ b/exercises/standard_library_types/rc1.rs
@@ -0,0 +1,98 @@
+// rc1.rs
+// In this exercise, we want to express the concept of multiple owners via the Rc<T> type.
+// This is a model of our solar system - there is a Sun type and multiple Planets.
+// The Planets take ownership of the sun, indicating that they revolve around the sun.
+
+// Make this code compile by using the proper Rc primitives to express that the sun has multiple owners.
+
+// I AM NOT DONE
+use std::rc::Rc;
+
+#[derive(Debug)]
+struct Sun {}
+
+#[derive(Debug)]
+enum Planet {
+    Mercury(Rc<Sun>),
+    Venus(Rc<Sun>),
+    Earth(Rc<Sun>),
+    Mars(Rc<Sun>),
+    Jupiter(Rc<Sun>),
+    Saturn(Rc<Sun>),
+    Uranus(Rc<Sun>),
+    Neptune(Rc<Sun>),
+}
+
+impl Planet {
+    fn details(&self) {
+        println!("Hi from {:?}!", self)
+    }
+}
+
+fn main() {
+    let sun = Rc::new(Sun {});
+    println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
+
+    let mercury = Planet::Mercury(Rc::clone(&sun));
+    println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
+    mercury.details();
+
+    let venus = Planet::Venus(Rc::clone(&sun));
+    println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
+    venus.details();
+
+    let earth = Planet::Earth(Rc::clone(&sun));
+    println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
+    earth.details();
+
+    let mars = Planet::Mars(Rc::clone(&sun));
+    println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
+    mars.details();
+
+    let jupiter = Planet::Jupiter(Rc::clone(&sun));
+    println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
+    jupiter.details();
+
+    // TODO
+    let saturn = Planet::Saturn(Rc::new(Sun {}));
+    println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
+    saturn.details();
+
+    // TODO
+    let uranus = Planet::Uranus(Rc::new(Sun {}));
+    println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
+    uranus.details();
+
+    // TODO
+    let neptune = Planet::Neptune(Rc::new(Sun {}));
+    println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
+    neptune.details();
+
+    assert_eq!(Rc::strong_count(&sun), 9);
+
+    drop(neptune);
+    println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
+
+    drop(uranus);
+    println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
+
+    drop(saturn);
+    println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
+
+    drop(jupiter);
+    println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
+
+    drop(mars);
+    println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
+
+    // TODO
+    println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
+
+    // TODO
+    println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
+
+    // TODO
+    println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
+
+    assert_eq!(Rc::strong_count(&sun), 1);
+}
diff --git a/info.toml b/info.toml
index 5b7b9b43..a72c0147 100644
--- a/info.toml
+++ b/info.toml
@@ -929,6 +929,20 @@ is too much of a struggle, consider reading through all of Chapter 16 in the boo
 https://doc.rust-lang.org/stable/book/ch16-00-concurrency.html
 """
 
+[[exercises]]
+name = "rc1"
+path = "exercises/standard_library_types/rc1.rs"
+mode = "compile"
+hint = """
+This is a straightforward exercise to use the Rc<T> type. Each Planet has
+ownership of the Sun, and uses Rc::clone() to increment the reference count of the Sun.
+After using drop() to move the Planets out of scope individually, the reference count goes down.
+In the end the sun only has one reference again, to itself. See more at:
+https://doc.rust-lang.org/book/ch15-04-rc.html
+
+* Unforunately Pluto is no longer considered a planet :(
+"""
+
 # THREADS
 
 [[exercises]]