diff options
Diffstat (limited to 'src/doc/book/listings/ch15-smart-pointers')
103 files changed, 1282 insertions, 0 deletions
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.lock new file mode 100644 index 000000000..8c125fc84 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "box-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.toml new file mode 100644 index 000000000..690385c7a --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "box-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-01/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/src/main.rs new file mode 100644 index 000000000..8da1d905d --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + let b = Box::new(5); + println!("b = {}", b); +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.lock new file mode 100644 index 000000000..a792c49aa --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.toml new file mode 100644 index 000000000..dce1515c3 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-02/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/src/main.rs new file mode 100644 index 000000000..84640b9b9 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/src/main.rs @@ -0,0 +1,8 @@ +// ANCHOR: here +enum List { + Cons(i32, List), + Nil, +} +// ANCHOR_END: here + +fn main() {} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.lock new file mode 100644 index 000000000..a792c49aa --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.toml new file mode 100644 index 000000000..dce1515c3 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt new file mode 100644 index 000000000..437d74b5c --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt @@ -0,0 +1,27 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) +error[E0072]: recursive type `List` has infinite size + --> src/main.rs:1:1 + | +1 | enum List { + | ^^^^^^^^^ recursive type has infinite size +2 | Cons(i32, List), + | ---- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` representable + | +2 | Cons(i32, Box<List>), + | ++++ + + +error[E0391]: cycle detected when computing drop-check constraints for `List` + --> src/main.rs:1:1 + | +1 | enum List { + | ^^^^^^^^^ + | + = note: ...which immediately requires computing drop-check constraints for `List` again + = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, constness: NotConst }, value: List } }` + +Some errors have detailed explanations: E0072, E0391. +For more information about an error, try `rustc --explain E0072`. +error: could not compile `cons-list` due to 2 previous errors diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/src/main.rs new file mode 100644 index 000000000..a96f3d7b1 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/src/main.rs @@ -0,0 +1,12 @@ +enum List { + Cons(i32, List), + Nil, +} + +// ANCHOR: here +use crate::List::{Cons, Nil}; + +fn main() { + let list = Cons(1, Cons(2, Cons(3, Nil))); +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.lock new file mode 100644 index 000000000..a792c49aa --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.toml new file mode 100644 index 000000000..dce1515c3 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-05/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/src/main.rs new file mode 100644 index 000000000..22f7d8338 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/src/main.rs @@ -0,0 +1,10 @@ +enum List { + Cons(i32, Box<List>), + Nil, +} + +use crate::List::{Cons, Nil}; + +fn main() { + let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil)))))); +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.lock new file mode 100644 index 000000000..4297c6733 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.toml new file mode 100644 index 000000000..67ec198f7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-06/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/src/main.rs new file mode 100644 index 000000000..174b620cf --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let x = 5; + let y = &x; + + assert_eq!(5, x); + assert_eq!(5, *y); +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.lock new file mode 100644 index 000000000..4297c6733 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.toml new file mode 100644 index 000000000..67ec198f7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-07/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/src/main.rs new file mode 100644 index 000000000..4933a416b --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let x = 5; + let y = Box::new(x); + + assert_eq!(5, x); + assert_eq!(5, *y); +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.lock new file mode 100644 index 000000000..4297c6733 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.toml new file mode 100644 index 000000000..67ec198f7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-08/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/src/main.rs new file mode 100644 index 000000000..f48594673 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/src/main.rs @@ -0,0 +1,11 @@ +// ANCHOR: here +struct MyBox<T>(T); + +impl<T> MyBox<T> { + fn new(x: T) -> MyBox<T> { + MyBox(x) + } +} +// ANCHOR_END: here + +fn main() {} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.lock new file mode 100644 index 000000000..4297c6733 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.toml new file mode 100644 index 000000000..67ec198f7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-09/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/output.txt new file mode 100644 index 000000000..75e5f1c8c --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/output.txt @@ -0,0 +1,10 @@ +$ cargo run + Compiling deref-example v0.1.0 (file:///projects/deref-example) +error[E0614]: type `MyBox<{integer}>` cannot be dereferenced + --> src/main.rs:14:19 + | +14 | assert_eq!(5, *y); + | ^^ + +For more information about this error, try `rustc --explain E0614`. +error: could not compile `deref-example` due to previous error diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-09/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/src/main.rs new file mode 100644 index 000000000..d07f2d78a --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/src/main.rs @@ -0,0 +1,17 @@ +struct MyBox<T>(T); + +impl<T> MyBox<T> { + fn new(x: T) -> MyBox<T> { + MyBox(x) + } +} + +// ANCHOR: here +fn main() { + let x = 5; + let y = MyBox::new(x); + + assert_eq!(5, x); + assert_eq!(5, *y); +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.lock new file mode 100644 index 000000000..4297c6733 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.toml new file mode 100644 index 000000000..67ec198f7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-10/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/src/main.rs new file mode 100644 index 000000000..cce754d08 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/src/main.rs @@ -0,0 +1,27 @@ +// ANCHOR: here +use std::ops::Deref; + +impl<T> Deref for MyBox<T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} +// ANCHOR_END: here + +struct MyBox<T>(T); + +impl<T> MyBox<T> { + fn new(x: T) -> MyBox<T> { + MyBox(x) + } +} + +fn main() { + let x = 5; + let y = MyBox::new(x); + + assert_eq!(5, x); + assert_eq!(5, *y); +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.lock new file mode 100644 index 000000000..4297c6733 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.toml new file mode 100644 index 000000000..67ec198f7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-11/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/src/main.rs new file mode 100644 index 000000000..77a88c91f --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/src/main.rs @@ -0,0 +1,7 @@ +// ANCHOR: here +fn hello(name: &str) { + println!("Hello, {name}!"); +} +// ANCHOR_END: here + +fn main() {} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.lock new file mode 100644 index 000000000..4297c6733 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.toml new file mode 100644 index 000000000..67ec198f7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-12/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/src/main.rs new file mode 100644 index 000000000..8cd3893cb --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/src/main.rs @@ -0,0 +1,28 @@ +use std::ops::Deref; + +impl<T> Deref for MyBox<T> { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +struct MyBox<T>(T); + +impl<T> MyBox<T> { + fn new(x: T) -> MyBox<T> { + MyBox(x) + } +} + +fn hello(name: &str) { + println!("Hello, {name}!"); +} + +// ANCHOR: here +fn main() { + let m = MyBox::new(String::from("Rust")); + hello(&m); +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.lock new file mode 100644 index 000000000..4297c6733 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.toml new file mode 100644 index 000000000..67ec198f7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-13/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/src/main.rs new file mode 100644 index 000000000..9debe2a31 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/src/main.rs @@ -0,0 +1,28 @@ +use std::ops::Deref; + +impl<T> Deref for MyBox<T> { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +struct MyBox<T>(T); + +impl<T> MyBox<T> { + fn new(x: T) -> MyBox<T> { + MyBox(x) + } +} + +fn hello(name: &str) { + println!("Hello, {name}!"); +} + +// ANCHOR: here +fn main() { + let m = MyBox::new(String::from("Rust")); + hello(&(*m)[..]); +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.lock new file mode 100644 index 000000000..eb8a2817a --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "drop-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.toml new file mode 100644 index 000000000..1e4c99481 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "drop-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-14/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/output.txt new file mode 100644 index 000000000..4e795949a --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/output.txt @@ -0,0 +1,7 @@ +$ cargo run + Compiling drop-example v0.1.0 (file:///projects/drop-example) + Finished dev [unoptimized + debuginfo] target(s) in 0.60s + Running `target/debug/drop-example` +CustomSmartPointers created. +Dropping CustomSmartPointer with data `other stuff`! +Dropping CustomSmartPointer with data `my stuff`! diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-14/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/src/main.rs new file mode 100644 index 000000000..231612ae6 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/src/main.rs @@ -0,0 +1,19 @@ +struct CustomSmartPointer { + data: String, +} + +impl Drop for CustomSmartPointer { + fn drop(&mut self) { + println!("Dropping CustomSmartPointer with data `{}`!", self.data); + } +} + +fn main() { + let c = CustomSmartPointer { + data: String::from("my stuff"), + }; + let d = CustomSmartPointer { + data: String::from("other stuff"), + }; + println!("CustomSmartPointers created."); +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.lock new file mode 100644 index 000000000..eb8a2817a --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "drop-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.toml new file mode 100644 index 000000000..1e4c99481 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "drop-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-15/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/output.txt new file mode 100644 index 000000000..a38c9ccb7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/output.txt @@ -0,0 +1,13 @@ +$ cargo run + Compiling drop-example v0.1.0 (file:///projects/drop-example) +error[E0040]: explicit use of destructor method + --> src/main.rs:16:7 + | +16 | c.drop(); + | --^^^^-- + | | | + | | explicit destructor calls not allowed + | help: consider using `drop` function: `drop(c)` + +For more information about this error, try `rustc --explain E0040`. +error: could not compile `drop-example` due to previous error diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-15/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/src/main.rs new file mode 100644 index 000000000..ff3b391a9 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/src/main.rs @@ -0,0 +1,20 @@ +struct CustomSmartPointer { + data: String, +} + +impl Drop for CustomSmartPointer { + fn drop(&mut self) { + println!("Dropping CustomSmartPointer with data `{}`!", self.data); + } +} + +// ANCHOR: here +fn main() { + let c = CustomSmartPointer { + data: String::from("some data"), + }; + println!("CustomSmartPointer created."); + c.drop(); + println!("CustomSmartPointer dropped before the end of main."); +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.lock new file mode 100644 index 000000000..eb8a2817a --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "drop-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.toml new file mode 100644 index 000000000..1e4c99481 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "drop-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-16/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/output.txt new file mode 100644 index 000000000..e960cd89a --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/output.txt @@ -0,0 +1,7 @@ +$ cargo run + Compiling drop-example v0.1.0 (file:///projects/drop-example) + Finished dev [unoptimized + debuginfo] target(s) in 0.73s + Running `target/debug/drop-example` +CustomSmartPointer created. +Dropping CustomSmartPointer with data `some data`! +CustomSmartPointer dropped before the end of main. diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-16/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/src/main.rs new file mode 100644 index 000000000..f11715c45 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/src/main.rs @@ -0,0 +1,20 @@ +struct CustomSmartPointer { + data: String, +} + +impl Drop for CustomSmartPointer { + fn drop(&mut self) { + println!("Dropping CustomSmartPointer with data `{}`!", self.data); + } +} + +// ANCHOR: here +fn main() { + let c = CustomSmartPointer { + data: String::from("some data"), + }; + println!("CustomSmartPointer created."); + drop(c); + println!("CustomSmartPointer dropped before the end of main."); +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.lock new file mode 100644 index 000000000..a792c49aa --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.toml new file mode 100644 index 000000000..dce1515c3 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-17/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/output.txt new file mode 100644 index 000000000..ab314d883 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/output.txt @@ -0,0 +1,14 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) +error[E0382]: use of moved value: `a` + --> src/main.rs:11:30 + | +9 | let a = Cons(5, Box::new(Cons(10, Box::new(Nil)))); + | - move occurs because `a` has type `List`, which does not implement the `Copy` trait +10 | let b = Cons(3, Box::new(a)); + | - value moved here +11 | let c = Cons(4, Box::new(a)); + | ^ value used here after move + +For more information about this error, try `rustc --explain E0382`. +error: could not compile `cons-list` due to previous error diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-17/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/src/main.rs new file mode 100644 index 000000000..47c33e4c4 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/src/main.rs @@ -0,0 +1,12 @@ +enum List { + Cons(i32, Box<List>), + Nil, +} + +use crate::List::{Cons, Nil}; + +fn main() { + let a = Cons(5, Box::new(Cons(10, Box::new(Nil)))); + let b = Cons(3, Box::new(a)); + let c = Cons(4, Box::new(a)); +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.lock new file mode 100644 index 000000000..a792c49aa --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.toml new file mode 100644 index 000000000..dce1515c3 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-18/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/src/main.rs new file mode 100644 index 000000000..602f7de40 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/src/main.rs @@ -0,0 +1,13 @@ +enum List { + Cons(i32, Rc<List>), + Nil, +} + +use crate::List::{Cons, Nil}; +use std::rc::Rc; + +fn main() { + let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); + let b = Cons(3, Rc::clone(&a)); + let c = Cons(4, Rc::clone(&a)); +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.lock new file mode 100644 index 000000000..a792c49aa --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.toml new file mode 100644 index 000000000..dce1515c3 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-19/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/output.txt new file mode 100644 index 000000000..6a8cc8efe --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/output.txt @@ -0,0 +1,8 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) + Finished dev [unoptimized + debuginfo] target(s) in 0.45s + Running `target/debug/cons-list` +count after creating a = 1 +count after creating b = 2 +count after creating c = 3 +count after c goes out of scope = 2 diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-19/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/src/main.rs new file mode 100644 index 000000000..1bd7bc533 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/src/main.rs @@ -0,0 +1,21 @@ +enum List { + Cons(i32, Rc<List>), + Nil, +} + +use crate::List::{Cons, Nil}; +use std::rc::Rc; + +// ANCHOR: here +fn main() { + let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); + println!("count after creating a = {}", Rc::strong_count(&a)); + let b = Cons(3, Rc::clone(&a)); + println!("count after creating b = {}", Rc::strong_count(&a)); + { + let c = Cons(4, Rc::clone(&a)); + println!("count after creating c = {}", Rc::strong_count(&a)); + } + println!("count after c goes out of scope = {}", Rc::strong_count(&a)); +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.lock new file mode 100644 index 000000000..4dc2226a5 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "limit-tracker" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.toml new file mode 100644 index 000000000..98c3f537c --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-20/src/lib.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/src/lib.rs new file mode 100644 index 000000000..a5181834c --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/src/lib.rs @@ -0,0 +1,38 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ + pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >= 1.0 { + self.messenger.send("Error: You are over your quota!"); + } else if percentage_of_max >= 0.9 { + self.messenger + .send("Urgent warning: You've used up over 90% of your quota!"); + } else if percentage_of_max >= 0.75 { + self.messenger + .send("Warning: You've used up over 75% of your quota!"); + } + } +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.lock new file mode 100644 index 000000000..4dc2226a5 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "limit-tracker" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.toml new file mode 100644 index 000000000..98c3f537c --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-21/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/output.txt new file mode 100644 index 000000000..6b07b66ea --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/output.txt @@ -0,0 +1,14 @@ +$ cargo test + Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker) +error[E0596]: cannot borrow `self.sent_messages` as mutable, as it is behind a `&` reference + --> src/lib.rs:58:13 + | +2 | fn send(&self, msg: &str); + | ----- help: consider changing that to be a mutable reference: `&mut self` +... +58 | self.sent_messages.push(String::from(message)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + +For more information about this error, try `rustc --explain E0596`. +error: could not compile `limit-tracker` due to previous error +warning: build failed, waiting for other jobs to finish... diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-21/src/lib.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/src/lib.rs new file mode 100644 index 000000000..4572d4313 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/src/lib.rs @@ -0,0 +1,73 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ + pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >= 1.0 { + self.messenger.send("Error: You are over your quota!"); + } else if percentage_of_max >= 0.9 { + self.messenger + .send("Urgent warning: You've used up over 90% of your quota!"); + } else if percentage_of_max >= 0.75 { + self.messenger + .send("Warning: You've used up over 75% of your quota!"); + } + } +} + +// ANCHOR: here +#[cfg(test)] +mod tests { + use super::*; + + struct MockMessenger { + sent_messages: Vec<String>, + } + + impl MockMessenger { + fn new() -> MockMessenger { + MockMessenger { + sent_messages: vec![], + } + } + } + + impl Messenger for MockMessenger { + fn send(&self, message: &str) { + self.sent_messages.push(String::from(message)); + } + } + + #[test] + fn it_sends_an_over_75_percent_warning_message() { + let mock_messenger = MockMessenger::new(); + let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); + + limit_tracker.set_value(80); + + assert_eq!(mock_messenger.sent_messages.len(), 1); + } +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.lock new file mode 100644 index 000000000..4dc2226a5 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "limit-tracker" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.toml new file mode 100644 index 000000000..98c3f537c --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-22/src/lib.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/src/lib.rs new file mode 100644 index 000000000..a77ffa41c --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/src/lib.rs @@ -0,0 +1,78 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ + pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >= 1.0 { + self.messenger.send("Error: You are over your quota!"); + } else if percentage_of_max >= 0.9 { + self.messenger + .send("Urgent warning: You've used up over 90% of your quota!"); + } else if percentage_of_max >= 0.75 { + self.messenger + .send("Warning: You've used up over 75% of your quota!"); + } + } +} + +// ANCHOR: here +#[cfg(test)] +mod tests { + use super::*; + use std::cell::RefCell; + + struct MockMessenger { + sent_messages: RefCell<Vec<String>>, + } + + impl MockMessenger { + fn new() -> MockMessenger { + MockMessenger { + sent_messages: RefCell::new(vec![]), + } + } + } + + impl Messenger for MockMessenger { + fn send(&self, message: &str) { + self.sent_messages.borrow_mut().push(String::from(message)); + } + } + + #[test] + fn it_sends_an_over_75_percent_warning_message() { + // --snip-- + // ANCHOR_END: here + let mock_messenger = MockMessenger::new(); + let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); + + limit_tracker.set_value(80); + // ANCHOR: here + + // ANCHOR: here + assert_eq!(mock_messenger.sent_messages.borrow().len(), 1); + } +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.lock new file mode 100644 index 000000000..4dc2226a5 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "limit-tracker" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.toml new file mode 100644 index 000000000..98c3f537c --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt new file mode 100644 index 000000000..c44e69f13 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt @@ -0,0 +1,21 @@ +$ cargo test + Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker) + Finished test [unoptimized + debuginfo] target(s) in 0.91s + Running unittests src/lib.rs (target/debug/deps/limit_tracker-e599811fa246dbde) + +running 1 test +test tests::it_sends_an_over_75_percent_warning_message ... FAILED + +failures: + +---- tests::it_sends_an_over_75_percent_warning_message stdout ---- +thread 'main' panicked at 'already borrowed: BorrowMutError', src/lib.rs:60:53 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::it_sends_an_over_75_percent_warning_message + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/src/lib.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/src/lib.rs new file mode 100644 index 000000000..7d288e680 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/src/lib.rs @@ -0,0 +1,78 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ + pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >= 1.0 { + self.messenger.send("Error: You are over your quota!"); + } else if percentage_of_max >= 0.9 { + self.messenger + .send("Urgent warning: You've used up over 90% of your quota!"); + } else if percentage_of_max >= 0.75 { + self.messenger + .send("Warning: You've used up over 75% of your quota!"); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::cell::RefCell; + + struct MockMessenger { + sent_messages: RefCell<Vec<String>>, + } + + impl MockMessenger { + fn new() -> MockMessenger { + MockMessenger { + sent_messages: RefCell::new(vec![]), + } + } + } + + // ANCHOR: here + impl Messenger for MockMessenger { + fn send(&self, message: &str) { + let mut one_borrow = self.sent_messages.borrow_mut(); + let mut two_borrow = self.sent_messages.borrow_mut(); + + one_borrow.push(String::from(message)); + two_borrow.push(String::from(message)); + } + } + // ANCHOR_END: here + + #[test] + fn it_sends_an_over_75_percent_warning_message() { + let mock_messenger = MockMessenger::new(); + let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); + + limit_tracker.set_value(80); + + assert_eq!(mock_messenger.sent_messages.borrow().len(), 1); + } +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.lock new file mode 100644 index 000000000..a792c49aa --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.toml new file mode 100644 index 000000000..dce1515c3 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-24/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/output.txt new file mode 100644 index 000000000..21b3530d9 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/output.txt @@ -0,0 +1,7 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) + Finished dev [unoptimized + debuginfo] target(s) in 0.63s + Running `target/debug/cons-list` +a after = Cons(RefCell { value: 15 }, Nil) +b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil)) +c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil)) diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-24/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/src/main.rs new file mode 100644 index 000000000..e225bd862 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/src/main.rs @@ -0,0 +1,24 @@ +#[derive(Debug)] +enum List { + Cons(Rc<RefCell<i32>>, Rc<List>), + Nil, +} + +use crate::List::{Cons, Nil}; +use std::cell::RefCell; +use std::rc::Rc; + +fn main() { + let value = Rc::new(RefCell::new(5)); + + let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil))); + + let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a)); + let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a)); + + *value.borrow_mut() += 10; + + println!("a after = {:?}", a); + println!("b after = {:?}", b); + println!("c after = {:?}", c); +} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.lock new file mode 100644 index 000000000..a792c49aa --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.toml new file mode 100644 index 000000000..dce1515c3 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-25/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/src/main.rs new file mode 100644 index 000000000..f36c7fd06 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/src/main.rs @@ -0,0 +1,20 @@ +use crate::List::{Cons, Nil}; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Debug)] +enum List { + Cons(i32, RefCell<Rc<List>>), + Nil, +} + +impl List { + fn tail(&self) -> Option<&RefCell<Rc<List>>> { + match self { + Cons(_, item) => Some(item), + Nil => None, + } + } +} + +fn main() {} diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.lock new file mode 100644 index 000000000..a792c49aa --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.toml new file mode 100644 index 000000000..dce1515c3 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-26/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/output.txt new file mode 100644 index 000000000..8b8eb40b6 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/output.txt @@ -0,0 +1,11 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) + Finished dev [unoptimized + debuginfo] target(s) in 0.53s + Running `target/debug/cons-list` +a initial rc count = 1 +a next item = Some(RefCell { value: Nil }) +a rc count after b creation = 2 +b initial rc count = 1 +b next item = Some(RefCell { value: Cons(5, RefCell { value: Nil }) }) +b rc count after changing a = 2 +a rc count after changing a = 2 diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-26/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/src/main.rs new file mode 100644 index 000000000..08963aaa5 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/src/main.rs @@ -0,0 +1,44 @@ +use crate::List::{Cons, Nil}; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Debug)] +enum List { + Cons(i32, RefCell<Rc<List>>), + Nil, +} + +impl List { + fn tail(&self) -> Option<&RefCell<Rc<List>>> { + match self { + Cons(_, item) => Some(item), + Nil => None, + } + } +} + +// ANCHOR: here +fn main() { + let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil)))); + + println!("a initial rc count = {}", Rc::strong_count(&a)); + println!("a next item = {:?}", a.tail()); + + let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a)))); + + println!("a rc count after b creation = {}", Rc::strong_count(&a)); + println!("b initial rc count = {}", Rc::strong_count(&b)); + println!("b next item = {:?}", b.tail()); + + if let Some(link) = a.tail() { + *link.borrow_mut() = Rc::clone(&b); + } + + println!("b rc count after changing a = {}", Rc::strong_count(&b)); + println!("a rc count after changing a = {}", Rc::strong_count(&a)); + + // Uncomment the next line to see that we have a cycle; + // it will overflow the stack + // println!("a next item = {:?}", a.tail()); +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.lock new file mode 100644 index 000000000..dd1f00a87 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "tree" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.toml new file mode 100644 index 000000000..0bbf897d0 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "tree" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-27/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/src/main.rs new file mode 100644 index 000000000..335d154dd --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/src/main.rs @@ -0,0 +1,24 @@ +// ANCHOR: here +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Debug)] +struct Node { + value: i32, + children: RefCell<Vec<Rc<Node>>>, +} +// ANCHOR_END: here + +// ANCHOR: there +fn main() { + let leaf = Rc::new(Node { + value: 3, + children: RefCell::new(vec![]), + }); + + let branch = Rc::new(Node { + value: 5, + children: RefCell::new(vec![Rc::clone(&leaf)]), + }); +} +// ANCHOR_END: there diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.lock new file mode 100644 index 000000000..dd1f00a87 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "tree" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.toml new file mode 100644 index 000000000..0bbf897d0 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "tree" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-28/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/src/main.rs new file mode 100644 index 000000000..fabd1cbce --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/src/main.rs @@ -0,0 +1,33 @@ +// ANCHOR: here +use std::cell::RefCell; +use std::rc::{Rc, Weak}; + +#[derive(Debug)] +struct Node { + value: i32, + parent: RefCell<Weak<Node>>, + children: RefCell<Vec<Rc<Node>>>, +} +// ANCHOR_END: here + +// ANCHOR: there +fn main() { + let leaf = Rc::new(Node { + value: 3, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec![]), + }); + + println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); + + let branch = Rc::new(Node { + value: 5, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec![Rc::clone(&leaf)]), + }); + + *leaf.parent.borrow_mut() = Rc::downgrade(&branch); + + println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); +} +// ANCHOR_END: there diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.lock new file mode 100644 index 000000000..dd1f00a87 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "tree" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.toml new file mode 100644 index 000000000..0bbf897d0 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "tree" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-29/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/src/main.rs new file mode 100644 index 000000000..ea13df0eb --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/src/main.rs @@ -0,0 +1,54 @@ +use std::cell::RefCell; +use std::rc::{Rc, Weak}; + +#[derive(Debug)] +struct Node { + value: i32, + parent: RefCell<Weak<Node>>, + children: RefCell<Vec<Rc<Node>>>, +} + +// ANCHOR: here +fn main() { + let leaf = Rc::new(Node { + value: 3, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec![]), + }); + + println!( + "leaf strong = {}, weak = {}", + Rc::strong_count(&leaf), + Rc::weak_count(&leaf), + ); + + { + let branch = Rc::new(Node { + value: 5, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec![Rc::clone(&leaf)]), + }); + + *leaf.parent.borrow_mut() = Rc::downgrade(&branch); + + println!( + "branch strong = {}, weak = {}", + Rc::strong_count(&branch), + Rc::weak_count(&branch), + ); + + println!( + "leaf strong = {}, weak = {}", + Rc::strong_count(&leaf), + Rc::weak_count(&leaf), + ); + } + + println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); + println!( + "leaf strong = {}, weak = {}", + Rc::strong_count(&leaf), + Rc::weak_count(&leaf), + ); +} +// ANCHOR_END: here diff --git a/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock new file mode 100644 index 000000000..340f6604a --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "borrowing" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml new file mode 100644 index 000000000..16f92447f --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "borrowing" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt new file mode 100644 index 000000000..8e84746ee --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling borrowing v0.1.0 (file:///projects/borrowing) +error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable + --> src/main.rs:3:13 + | +2 | let x = 5; + | - help: consider changing this to be mutable: `mut x` +3 | let y = &mut x; + | ^^^^^^ cannot borrow as mutable + +For more information about this error, try `rustc --explain E0596`. +error: could not compile `borrowing` due to previous error diff --git a/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs new file mode 100644 index 000000000..8f48d41c1 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + let x = 5; + let y = &mut x; +} diff --git a/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock new file mode 100644 index 000000000..4297c6733 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml new file mode 100644 index 000000000..67ec198f7 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt new file mode 100644 index 000000000..a03cc34e2 --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt @@ -0,0 +1,23 @@ +$ cargo run + Compiling deref-example v0.1.0 (file:///projects/deref-example) +error[E0277]: can't compare `{integer}` with `&{integer}` + --> src/main.rs:6:5 + | +6 | assert_eq!(5, y); + | ^^^^^^^^^^^^^^^^ no implementation for `{integer} == &{integer}` + | + = help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}` + = help: the following other types implement trait `PartialEq<Rhs>`: + f32 + f64 + i128 + i16 + i32 + i64 + i8 + isize + and 6 others + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `deref-example` due to previous error diff --git a/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs new file mode 100644 index 000000000..4e20cae0b --- /dev/null +++ b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let x = 5; + let y = &x; + + assert_eq!(5, x); + assert_eq!(5, y); +} |