From 2a696fdfa933e4891d4b9b8ce908446a555c57d5 Mon Sep 17 00:00:00 2001
From: Rowan Torbitzky-Lane <rowan.a.tl@protonmail.com>
Date: Wed, 19 Mar 2025 21:55:11 -0500
Subject: [PATCH] at summary of ch4.2

---
 ch4/refs_and_borrow/src/main.rs | 71 ++++++++++++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 2 deletions(-)

diff --git a/ch4/refs_and_borrow/src/main.rs b/ch4/refs_and_borrow/src/main.rs
index 6d8533d..5be8cb2 100644
--- a/ch4/refs_and_borrow/src/main.rs
+++ b/ch4/refs_and_borrow/src/main.rs
@@ -54,8 +54,54 @@ fn main() {
 
     // Data in Rust should never be aliased and mutated at the same time
 
-    // Stopped here:
-    // https://rust-book.cs.brown.edu/ch04-02-references-and-borrowing.html#references-change-permissions-on-places
+    // -----------------------------------------------------------------------------
+    // References Change Permissions on Places
+    //
+    // Read (R): Data can be copied to another location
+    // Write (W): Data can be mutated
+    // Own (O): Dta can be moved or dropped
+    // These permissions only exist in the compiler, not at runtime.
+    // Default permission are RO, mut makes W
+    //   References can temporarily remove these permissions.
+    // Permissions are defined on places and not just variables
+    //   A place being anything to the left of the = sign
+    //     Variables like a, Dereferences like *a, array accesses like a[0]
+
+    // -----------------------------------------------------------------------------
+    // Borrow checker finds permissions violations
+
+    // Anytime a place is used, Rust expects that place to have certain
+    //   permissions depending on the operation
+
+    // -----------------------------------------------------------------------------
+    // mutable references provide unique and non-owning access to data
+
+    let mut v: Vec<i32> = vec![1, 2, 3];
+    let num: &mut i32 = &mut v[2];
+    *num += 1;
+    println!("Third element is {}", *num); // actually changes the 2nd element
+    println!("Vector is now {:?}", v);
+
+    // temporarily "downgrade" to a read-only reference
+    let mut v: Vec<i32> = vec![1, 2, 3];
+    let num: &mut i32 = &mut v[2];
+    let num2: &i32 = &*num;
+    println!("{} {}", *num, *num2);
+
+    // -----------------------------------------------------------------------------
+    // Permissions are returned at the end of a references lifetime
+
+    let mut x = 1;
+    let y = &x;
+    let z = *y;
+    x += z;
+    println!("final x val: {x}");
+
+    // -----------------------------------------------------------------------------
+    // Data must outlive all of its references
+
+    // Ended at:
+    // https://rust-book.cs.brown.edu/ch04-02-references-and-borrowing.html#summary
 }
 
 fn greet(g1: String, g2: String) {
@@ -70,3 +116,24 @@ fn greet_ret(g1: String, g2: String) -> (String, String) {
     println!("{} {}!", g1, g2);
     (g1, g2)
 }
+
+fn ascii_capitalize(v: &mut Vec<char>) {
+    let c = &v[0]; // *v has permissions R, W taken away
+    if c.is_ascii_lowercase() {
+        let up = c.to_ascii_uppercase(); // *v has permissions R, W is given
+        v[0] = up;
+    } else {
+        // *v has R, W is given
+        println!("Already Capitalized {:?}", v);
+    }
+}
+
+fn first(strings: &Vec<String>) -> &String {
+    // This function introduces the flow permission, F.
+    // F doesn't change throughout the body of a function
+    let s_ref = &strings[0];
+    s_ref
+}
+
+// Doesn't know whether &String is a reference to either strings or default
+// fn first_or(strings: &Vec<String>, default: &String) -> &String {}