diff --git a/Cargo.lock b/Cargo.lock index ce90dbc..ef9bc7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,150 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "memchr" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + [[package]] name = "playground" version = "0.1.0" +dependencies = [ + "futures", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/Cargo.toml b/Cargo.toml index c92d524..f61182a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] +futures = "0.3.32" diff --git a/src/arrays.rs b/src/arrays.rs index 9c4ce23..5e205a9 100644 --- a/src/arrays.rs +++ b/src/arrays.rs @@ -1,4 +1,5 @@ #[derive(Debug, PartialEq)] +#[allow(dead_code)] pub struct EmptyListError; // implementing Error for my error to satisfy Box @@ -13,23 +14,24 @@ impl std::fmt::Display for EmptyListError { } // Result<...,Box> is overkill -// this is intuitive enough for caller error detection +// this is intuitive enough for caller error detection // actually probably should use Option instead, but this is better for extension +#[allow(dead_code)] pub fn min_and_max(list: &[u32]) -> Result<(u32, u32), EmptyListError> { if list.is_empty() { return Err(EmptyListError); } - let mut min:u32 = 100; - let mut max:u32 = 0; + let mut min: u32 = 100; + let mut max: u32 = 0; for i in list { if *i > max { max = *i; - } + } if *i < min { min = *i; } - } - Ok((min,max)) + } + Ok((min, max)) } #[cfg(test)] @@ -46,14 +48,14 @@ mod tests { println!("Expected: {}", *(empty_min_and_max.as_ref().err().unwrap())); // array - contiguous, entirely on the stack, fixed at compile time, no pointer indirection - let l = [ 1, 2, 10, 100, 50, 75, 36, 21]; + let l = [1, 2, 10, 100, 50, 75, 36, 21]; let l_min_and_max = min_and_max(&l); assert!(l_min_and_max.as_ref().unwrap().0 == 1); assert!(l_min_and_max.as_ref().unwrap().1 == 100); // vec - stack: ptr, len, cap; ptr -> heap: contiguous allocation of capacity // when variable goes out of scope drop() is called to deallocate the heap - let v = vec![1,2,3]; + let v = vec![1, 2, 3]; let v_min_and_max = min_and_max(&v); assert!(v_min_and_max.as_ref().unwrap().0 == 1); assert!(v_min_and_max.as_ref().unwrap().1 == 3); @@ -62,6 +64,5 @@ mod tests { let r = &s; println!("{}", *r); // works because there is no implicit move // let thing = *r; // doesn't work because String does not implement Copy trait - } } diff --git a/src/async_play.rs b/src/async_play.rs new file mode 100644 index 0000000..df41f52 --- /dev/null +++ b/src/async_play.rs @@ -0,0 +1,22 @@ +use std::{thread, time}; + +#[allow(dead_code)] +async fn do_something(number: i8) -> i8 { + println!("number {} is running", number); + let two_seconds = time::Duration::new(2, 0); + thread::sleep(two_seconds); + return 2; +} + +#[cfg(test)] +mod tests { + use super::*; // need access to functions above + + #[test] + fn test_async() { + let _ = async { + do_something(2).await; + }; + assert!(true); + } +} diff --git a/src/main.rs b/src/main.rs index 321042d..a767c08 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ -mod string; mod arrays; +mod async_play; mod fmt_debug; +mod string; // when a String is passed to this function a move occurs: // BUT only the stack allocation (ptr, len, cap) is copied over @@ -74,7 +75,7 @@ fn min_and_max(list: &[u32]) -> Result<(u32, u32), EmptyListError> { } fn main() { - println!("Hello, world!"); + println!("Learning Rust"); fmt_debug::test_report(); let s = String::new(); // no heap allocation until we add characters (capacity > 0) @@ -112,6 +113,4 @@ fn main() { let _s6 = String::from(s_lit); //underlying data copied to heap // todo: Cow - println!("Learning Rust"); } - diff --git a/src/string.rs b/src/string.rs index 75749f6..b20318f 100644 --- a/src/string.rs +++ b/src/string.rs @@ -1,4 +1,4 @@ -use std::rc::Rc; +//use std::rc::Rc; // when a String is passed to this function a move occurs: // BUT only the stack allocation (ptr, len, cap) is copied over @@ -7,16 +7,12 @@ use std::rc::Rc; // Why do we call it a "move"? // A move indicates ownership transfer, not data transfer #[allow(dead_code)] -fn takes_string(_s: String) { - -} +fn takes_string(_s: String) {} // You can do this, but you probably want &str // UNLESS you want `&mut String` #[allow(dead_code)] -fn takes_string_ref(_s: &String) { - -} +fn takes_string_ref(_s: &String) {} // Compilation error and warning: // rustc: the size for values of type `str` cannot be known at compilation time @@ -36,9 +32,7 @@ fn takes_string_ref(_s: &String) { // this is fine because now the variable is a fat pointer: pointer + length // it's the length aspect that makes us abot to work on the str #[allow(dead_code)] -fn takes_str_ref(_s: &str) { - -} +fn takes_str_ref(_s: &str) {} // yeah, we can do this fn _get_static_str() -> &'static str { @@ -49,6 +43,8 @@ fn _get_static_str() -> &'static str { // and run the test code only when you run cargo test, not when you run cargo build #[cfg(test)] mod tests { + use std::rc::Rc; + use super::*; // need access to functions above #[test] @@ -73,29 +69,29 @@ mod tests { takes_str_ref(&sss); // *sss dereferences the String into its underlying str takes_str_ref(&*sss); // same as this! - takes_str_ref(sss.as_ref()); // and this! + takes_str_ref(sss.as_ref()); // and this! let s4 = String::from("string4"); //let s4_slice = s4[0..]; // again we hit no size problem at compile time - let _s4_slice = &s4[0..]; // but this works, because the &str has the length! + let _s4_slice = &s4[0..]; // but this works, because the &str has the length! // literals // &'static str is held onto by &str: // that's the programs read-only binary let s_lit = "easy as pie, right?"; - let _s_lit2 : &str = "easy as pie, right?"; // same, data not copied, we just point to it + let _s_lit2: &str = "easy as pie, right?"; // same, data not copied, we just point to it let _s5 = String::from("literal is copied to heap"); // data copied to heap let _s6 = String::from(s_lit); //underlying data copied to heap // Box is owned, heap allocated, fixed size, immutable // where as `&str` is borrowed view, linked to source, immutable // both have (ptr, len) -> underlying mem - let _s7 : Box = "hello".into(); + let _s7: Box = "hello".into(); // Rc (single-threaded reference counting) // HEAP memory layout: // * counter (strong) - // * counter (weak) + // * counter (weak) // * len // * data // STACK memory: @@ -103,9 +99,9 @@ mod tests { // * len // // Why are there two lengths? - let rc_str : Rc = Rc::from("rc_str"); + let rc_str: Rc = Rc::from("rc_str"); // let rc_str2 : Rc = rc_str; // this moves - let rc_str2 : Rc = rc_str.clone(); // copy ptr, increment counter + let rc_str2: Rc = rc_str.clone(); // copy ptr, increment counter println!("printing {}", rc_str); println!("printing {}", rc_str); println!("printing {}", rc_str2);