### Example: File implements Seek Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.Seek.html Example showing how to use the Seek trait with a File, moving the cursor 42 bytes from the start of the file. ```rust use std::io; use std::io::prelude::*; use std::fs::File; use std::io::SeekFrom; fn main() -> io::Result<()> { let mut f = File::open("foo.txt")?; // move the cursor 42 bytes from the start of the file f.seek(SeekFrom::Start(42))?; Ok(()) } ``` -------------------------------- ### Proof::new example Source: https://docs.rs/rustreexo/latest/rustreexo/proof/struct.Proof.html Example usage of creating a new Proof instance. ```rust use bitcoin_hashes::Hash; use bitcoin_hashes::HashEngine; use rustreexo::proof::Proof; let targets = vec![0]; let mut proof_hashes = Vec::new(); let targets = vec![0]; // For proving 0, we need 01, 09 and 13's hashes. 00, 08, 12 and 14 can be calculated // Fill `proof_hashes` up with all hashes Proof::new(targets, proof_hashes); ``` -------------------------------- ### Read method example with File Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.Read.html Example for the `read` method, showing how to read up to 10 bytes from a file and print them. Requires `foo.txt` to exist. ```rust use std::io; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let mut f = File::open("foo.txt")?; let mut buffer = [0; 10]; // read up to 10 bytes let n = f.read(&mut buffer[..])?; println!("The bytes: {:?}", &buffer[..n]); Ok(()) } ``` -------------------------------- ### into_ok() example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/type.Result.html Shows how to use into_ok to get the contained Ok value without panicking. This is a nightly-only experimental API that fails to compile if the error type can actually occur. ```rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` -------------------------------- ### by_ref() example for Write Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.Write.html Creates a by-reference adapter for a Write instance, allowing the borrowed writer to be used directly. The example creates a file, borrows it with by_ref(), and writes bytes through the reference. ```rust use std::io::Write; use std::fs::File; fn main() -> std::io::Result<()> { let mut buffer = File::create("foo.txt")?; let reference = buffer.by_ref(); // we can use reference just like our original buffer reference.write_all(b"some bytes")?; Ok(()) } ``` -------------------------------- ### MemForest usage example Source: https://docs.rs/rustreexo/latest/rustreexo/mem_forest/index.html Shows how to create a MemForest, add leaves, remove leaves, and verify roots. The example uses BitcoinNodeHash for hashes and expects the accumulator to have one root after adding and removing leaves. ```rust use rustreexo::mem_forest::MemForest; use rustreexo::node_hash::AccumulatorHash; use rustreexo::node_hash::BitcoinNodeHash; let values = vec![0, 1, 2, 3, 4, 5, 6, 7]; let hashes: Vec = values .into_iter() .map(|i| BitcoinNodeHash::from([i; 32])) .collect(); let mut p = MemForest::::new(); p.modify(&hashes, &[]).expect("MemForest should not fail"); assert_eq!(p.get_roots().len(), 1); p.modify(&[], &hashes).expect("Still should not fail"); // Remove leaves from the accumulator assert_eq!(p.get_roots().len(), 1); assert_eq!(p.get_roots()[0].get_data(), BitcoinNodeHash::default()); ``` -------------------------------- ### unwrap() basic usage example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/type.Result.html Shows how to use the unwrap method to get the contained Ok value. This example demonstrates a successful case where the Result is Ok(2) and unwrap returns 2. ```rust let x: Result = Ok(2); assert_eq!(x.unwrap(), 2); ``` -------------------------------- ### Proof::new_with_hash example Source: https://docs.rs/rustreexo/latest/rustreexo/proof/struct.Proof.html Example usage of creating a new Proof instance with a specific hash type. ```rust use bitcoin_hashes::Hash; use bitcoin_hashes::HashEngine; use rustreexo::node_hash::BitcoinNodeHash; use rustreexo::proof::Proof; let targets = vec![0]; let mut proof_hashes = Vec::new(); let targets = vec![0]; // For proving 0, we need 01, 09 and 13's hashes. 00, 08, 12 and 14 can be calculated // Fill `proof_hashes` up with all hashes Proof::::new_with_hash(targets, proof_hashes); ``` -------------------------------- ### Example: Using pipe with a child process Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/fn.pipe.html Complete example showing how to create two pipes, spawn a child process (`cat`) that echoes input, write data, and read the output. Includes comments about potential deadlocks and the need to drop writers. ```rust use std::io::{Read, Write, pipe}; use std::process::Command; let (ping_reader, mut ping_writer) = pipe()?; let (mut pong_reader, pong_writer) = pipe()?; // Spawn a child process that echoes its input. let mut echo_command = Command::new("cat"); echo_command.stdin(ping_reader); echo_command.stdout(pong_writer); let mut echo_child = echo_command.spawn()?; // Send input to the child process. Note that because we're writing all the input before we // read any output, this could deadlock if the child's input and output pipe buffers both // filled up. Those buffers are usually at least a few KB, so "hello" is fine, but for longer // inputs we'd need to read and write at the same time, e.g. using threads. ping_writer.write_all(b"hello")?; // `cat` exits when it reads EOF from stdin, but that can't happen while any ping writer // remains open. We need to drop our ping writer, or read_to_string will deadlock below. drop(ping_writer); // The pong reader can't report EOF while any pong writer remains open. Our Command object is // holding a pong writer, and again read_to_string will deadlock if we don't drop it. drop(echo_command); let mut buf = String::new(); // Block until `cat` closes its stdout (a pong writer). pong_reader.read_to_string(&mut buf)?; assert_eq!(&buf, "hello"); // At this point we know `cat` has exited, but we still need to wait to clean up the "zombie". echo_child.wait()?; ``` -------------------------------- ### HashSet::is_subset example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashSet.html Checks whether one set is a subset of another. The example starts with an empty set (subset), adds 2 (still subset), then adds 4 (no longer subset). ```rust use std::collections::HashSet; let sup = HashSet::from([1, 2, 3]); let mut set = HashSet::new(); assert_eq!(set.is_subset(&sup), true); set.insert(2); assert_eq!(set.is_subset(&sup), true); set.insert(4); assert_eq!(set.is_subset(&sup), false); ``` -------------------------------- ### Example: Creating and modifying a Stump Source: https://docs.rs/rustreexo/latest/rustreexo/stump/index.html This example shows how to create a new empty Stump, define new outputs (utxos) and spent outputs (stxos), and call the modify method with a default Proof. The modify method returns a new Stump instead of modifying the old one, as it is a pure function. The example asserts that the operation succeeds and that the resulting roots match the utxos. ```rust use std::str::FromStr; use rustreexo::node_hash::BitcoinNodeHash; use rustreexo::proof::Proof; use rustreexo::stump::Stump; // Create a new empty Stump let s = Stump::new(); // The newly create outputs let utxos = vec![BitcoinNodeHash::from_str( "b151a956139bb821d4effa34ea95c17560e0135d1e4661fc23cedc3af49dac42", ) .unwrap()]; // The spent outputs let stxos = vec![]; // Modify the Stump, adding the new outputs and removing the spent ones, notice how // it returns a new Stump, instead of modifying the old one. This is due to the fact // that modify is a pure function that doesn't modify the old Stump. let s = s.modify(&utxos, &stxos, &Proof::::default()); assert!(s.is_ok()); assert_eq!(s.unwrap().0.roots, utxos); ``` -------------------------------- ### kind example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.Error.html Illustrates the kind method to get the ErrorKind. Prints 'AddrInUse' for a custom error with that kind. ```rust use std::io::{Error, ErrorKind}; fn print_error(err: Error) { println!("{:?}", err.kind()); } fn main() { // As no error has (visibly) occurred, this may print anything! // It likely prints a placeholder for unidentified (non-)errors. print_error(Error::last_os_error()); // Will print "AddrInUse". print_error(Error::new(ErrorKind::AddrInUse, "oh no!")); } ``` -------------------------------- ### fill_buf example: reading from stdin Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.BufRead.html Example for fill_buf, showing how to read from a locked standard input. It fills the buffer, prints it, and then consumes the bytes. ```rust use std::io; use std::io::prelude::*; let stdin = io::stdin(); let mut stdin = stdin.lock(); let buffer = stdin.fill_buf()?; // work with buffer println!("{buffer:?}"); // mark the bytes we worked with as read let length = buffer.len(); stdin.consume(length); ``` -------------------------------- ### Example: using try_clone with multiple processes Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.PipeReader.html This example demonstrates how to use try_clone to share the pipe reader and writer with multiple child processes. It writes a fixed number of characters to the pipe, spawns several processes that read and write back, and verifies the output. ```rust use std::fs; use std::io::{pipe, Write}; use std::process::Command; const NUM_SLOT: u8 = 2; const NUM_PROC: u8 = 5; const OUTPUT: &str = "work.txt"; let mut jobs = vec![]; let (reader, mut writer) = pipe()?; // Write NUM_SLOT characters the pipe. writer.write_all(&[b'|'; NUM_SLOT as usize])?; // Spawn several processes that read a character from the pipe, do some work, then // write back to the pipe. When the pipe is empty, the processes block, so only // NUM_SLOT processes can be working at any given time. for _ in 0..NUM_PROC { jobs.push( Command::new("bash") .args(["-c", &format!( "read -n 1\n\ echo -n 'x' >> '{OUTPUT}'\n\ echo -n '|'", ), ]) .stdin(reader.try_clone()?) .stdout(writer.try_clone()?) .spawn()?, ); } // Wait for all jobs to finish. for mut job in jobs { job.wait()?; } // Check our work and clean up. let xs = fs::read_to_string(OUTPUT)?; fs::remove_file(OUTPUT)?; assert_eq!(xs, "x".repeat(NUM_PROC.into())); ``` -------------------------------- ### get_mut example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashMap.html Demonstrates using get_mut to get a mutable reference to the value corresponding to a key and modify it. ```rust use std::collections::HashMap; let mut map = HashMap::new(); map.insert(1, "a"); if let Some(x) = map.get_mut(&1) { *x = "b"; } assert_eq!(map[&1], "b"); ``` -------------------------------- ### and_then() example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/type.Result.html Shows how to use and_then for control flow based on Result values. This example defines a function that squares a number and converts it to a string, returning an error on overflow. ```rust fn sq_then_to_string(x: u32) -> Result { x.checked_mul(x).map(|sq| sq.to_string()).ok_or("overflowed") } ``` -------------------------------- ### Rewind to start of stream with f.rewind() Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.Seek.html Uses `File` with read/write access, writes a string, rewinds to the beginning, then reads back and asserts the content. Shows the convenience method equivalent to `seek(SeekFrom::Start(0))`. Rewinding can fail, for example when it involves flushing a buffer, so the `?` operator propagates the `io::Result`. ```rust use std::io::{Read, Seek, Write}; use std::fs::OpenOptions; let mut f = OpenOptions::new() .write(true) .read(true) .create(true) .open("foo.txt")?; let hello = "Hello!\n"; write!(f, "{hello}")?; f.rewind()?; let mut buf = String::new(); f.read_to_string(&mut buf)?; assert_eq!(&buf, hello); ``` -------------------------------- ### read_until example: reading hyphen-delimited segments Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.BufRead.html Example for read_until using Cursor to read bytes until a delimiter, showing the returned byte counts and buffer contents. ```rust use std::io::{self, BufRead}; let mut cursor = io::Cursor::new(b"lorem-ipsum"); let mut buf = vec![]; // cursor is at 'l' let num_bytes = cursor.read_until(b'-', &mut buf) .expect("reading from cursor won't fail"); assert_eq!(num_bytes, 6); assert_eq!(buf, b"lorem-"); buf.clear(); // cursor is at 'i' let num_bytes = cursor.read_until(b'-', &mut buf) .expect("reading from cursor won't fail"); assert_eq!(num_bytes, 5); assert_eq!(buf, b"ipsum"); buf.clear(); // cursor is at EOF let num_bytes = cursor.read_until(b'-', &mut buf) .expect("reading from cursor won't fail"); assert_eq!(num_bytes, 0); assert_eq!(buf, b""); ``` -------------------------------- ### BitOr for HashSet: Union Example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashSet.html Demonstrates the union of two HashSets using the `|` operator. The resulting set contains all unique elements from both input sets. The example verifies the result by iterating and asserting the expected elements. ```rust use std::collections::HashSet; let a = HashSet::from([1, 2, 3]); let b = HashSet::from([3, 4, 5]); let set = &a | &b; let mut i = 0; let expected = [1, 2, 3, 4, 5]; for x in &set { assert!(expected.contains(x)); i += 1; } assert_eq!(i, expected.len()); ``` -------------------------------- ### Get a reference to the underlying reader Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.Take.html Shows how to use the `get_ref` method to get an immutable reference to the underlying reader. The example reads some bytes, then gets a reference to the file. ```rust use std::io; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let mut file = File::open("foo.txt")?; let mut buffer = [0; 5]; let mut handle = file.take(5); handle.read(&mut buffer)?; let file = handle.get_ref(); Ok(()) } ``` -------------------------------- ### Get a mutable reference to the underlying reader Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.Take.html Shows how to use the `get_mut` method to get a mutable reference to the underlying reader. The example reads some bytes, then gets a mutable reference to the file. ```rust use std::io; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let mut file = File::open("foo.txt")?; let mut buffer = [0; 5]; let mut handle = file.take(5); handle.read(&mut buffer)?; let file = handle.get_mut(); Ok(()) } ``` -------------------------------- ### Create and verify a Proof with rustreexo Source: https://docs.rs/rustreexo/latest/src/rustreexo/proof/mod.rs.html Example from the module documentation showing how to create a Stump, add UTXOs, build a Proof with target positions and proof hashes, and verify it. Requires the rustreexo crate and bitcoin_hashes. The proof is verified with assert! and expects success. ```rust use std::str::FromStr; use bitcoin_hashes::sha256; use bitcoin_hashes::Hash; use bitcoin_hashes::HashEngine; use rustreexo::node_hash::BitcoinNodeHash; use rustreexo::proof::Proof; use rustreexo::stump::Stump; let s = Stump::new(); // Creates a tree with those values as leaves let test_values: Vec = vec![0, 1, 2, 3, 4, 5, 6, 7]; // Targets are the nodes we intend to prove let targets = vec![0]; // The hashes used to prove an element. let mut proof_hashes = Vec::new(); proof_hashes.push( BitcoinNodeHash::from_str( "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a", ) .unwrap(), ); proof_hashes.push( BitcoinNodeHash::from_str( "9576f4ade6e9bc3a6458b506ce3e4e890df29cb14cb5d3d887672aef55647a2b", ) .unwrap(), ); proof_hashes.push( BitcoinNodeHash::from_str( "29590a14c1b09384b94a2c0e94bf821ca75b62eacebc478933ca88e97bbcbd7", ) .unwrap(), ); // Hashes of the leaves UTXOs we'll add to the accumulator let mut hashes = Vec::new(); for i in test_values { let mut engine = sha256::Hash::engine(); engine.input(&[i]); hashes.push(sha256::Hash::from_engine(engine).into()) } // Add the UTXOs to the accumulator let s = s.modify(&hashes, &vec![], &Proof::default()).unwrap().0; // Create a proof for the targets let p = Proof::new(targets, proof_hashes); // Verify the proof assert!(s.verify(&p, &vec![hashes[0]]).expect("This proof is valid")); ``` -------------------------------- ### Get reference to underlying writer with get_ref Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.BufWriter.html Gets a reference to the underlying writer. The example shows that the reference can be used like the buffer itself. ```rust use std::io::BufWriter; use std::net::TcpStream; let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); // we can use reference just like buffer let reference = buffer.get_ref(); ``` -------------------------------- ### take Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.PipeReader.html Creates an adapter which will read at most limit bytes from it. ```APIDOC ## take ### Description Creates an adapter which will read at most limit bytes from it. ### Method take ### Signature fn take(self, limit: u64) -> Take where Self: Sized ### Parameters - **limit** (u64) - Required - The maximum number of bytes to read. ### Returns Take - The take adapter. ``` -------------------------------- ### unwrap_or_default() example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/type.Result.html Shows how to use unwrap_or_default to get the contained Ok value or a default value for the type. This example parses strings to integers, returning 0 for poorly-formed strings. ```rust let good_year_from_input = "1909"; let bad_year_from_input = "190blarg"; let good_year = good_year_from_input.parse().unwrap_or_default(); let bad_year = bad_year_from_input.parse().unwrap_or_default(); assert_eq!(1909, good_year); assert_eq!(0, bad_year); ``` -------------------------------- ### get: Return a reference to a value if present Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashSet.html Shows how to get a reference to a value in the set if it exists. The value may be any borrowed form of the set's value type, but Hash and Eq on the borrowed form must match those for the value type. The example asserts that get(&2) returns Some(&2) and get(&4) returns None. ```rust use std::collections::HashSet; let set = HashSet::from([1, 2, 3]); assert_eq!(set.get(&2), Some(&2)); assert_eq!(set.get(&4), None); ``` -------------------------------- ### Read from a File using File::open and read methods Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/trait.Read.html Shows how to read from a file using `File::open` and the `read`, `read_to_end`, and `read_to_string` methods. The example uses `?` to propagate I/O errors and returns `io::Result<()>`. ```rust use std::io; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let mut f = File::open("foo.txt")?; let mut buffer = [0; 10]; // read up to 10 bytes f.read(&mut buffer)?; let mut buffer = Vec::new(); // read the whole file f.read_to_end(&mut buffer)?; // read into a String, so that you don't need to do the conversion. let mut buffer = String::new(); f.read_to_string(&mut buffer)?; // and more! See the other methods for more details. Ok(()) } ``` -------------------------------- ### Consume a Take and return the inner reader Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.Take.html Shows how to use the `into_inner` method to consume the Take and get the wrapped reader back. The example reads some bytes, then calls `into_inner` to get the original file. ```rust use std::io; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let mut file = File::open("foo.txt")?; let mut buffer = [0; 5]; let mut handle = file.take(5); handle.read(&mut buffer)?; let file = handle.into_inner(); Ok(()) } ``` -------------------------------- ### Verify a proof Source: https://docs.rs/rustreexo/latest/rustreexo/proof/struct.Proof.html Demonstrates how to create a tree, generate a proof for a target leaf, and verify it against the stump. ```rust use std::str::FromStr; use bitcoin_hashes::sha256; use bitcoin_hashes::Hash; use bitcoin_hashes::HashEngine; use rustreexo::node_hash::BitcoinNodeHash; use rustreexo::proof::Proof; use rustreexo::stump::Stump; let s = Stump::new(); // Creates a tree with those values as leaves let test_values: Vec = vec![0, 1, 2, 3, 4, 5, 6, 7]; // Targets are the nodes we intend to prove let targets = vec![0]; let mut proof_hashes = Vec::new(); // This tree will look like this // 14 // |-----------------\ // 12 13 // |---------\\ |--------\ // 08 09 10 11 // |----\ |----\ |----\ |----\ // 00 01 02 03 04 05 06 07 // For proving 0, we need 01, 09 and 13's hashes. 00, 08, 12 and 14 can be calculated proof_hashes.push( BitcoinNodeHash::from_str( "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a", ) .unwrap(), ); proof_hashes.push( BitcoinNodeHash::from_str( "9576f4ade6e9bc3a6458b506ce3e4e890df29cb14cb5d3d887672aef55647a2b", ) .unwrap(), ); proof_hashes.push( BitcoinNodeHash::from_str( "29590a14c1b09384b94a2c0e94bf821ca75b62eacebc47893397ca88e3bbcbd7", ) .unwrap(), ); let mut hashes = Vec::new(); for i in test_values { let mut engine = sha256::Hash::engine(); engine.input(&[i]); hashes.push(sha256::Hash::from_engine(engine).into()) } let s = s.modify(&hashes, &vec![], &Proof::default()).unwrap().0; let p = Proof::new(targets, proof_hashes); assert!(s.verify(&p, &[hashes[0]]).expect("This proof is valid")); ``` -------------------------------- ### Read from a File and print the bytes Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/trait.Read.html Shows how to read from a file and print the bytes read using `println!`. The example uses `read` to fill a buffer and prints the slice of bytes that were actually read. ```rust use std::io; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let mut f = File::open("foo.txt")?; let mut buffer = [0; 10]; // read up to 10 bytes let n = f.read(&mut buffer[..])?; println!("The bytes: {:?}", &buffer[..n]); Ok(()) } ``` -------------------------------- ### Get the limit of a Take reader Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.Take.html Shows how to use the `limit` method to get the number of bytes that can be read before EOF. The example opens a file and creates a Take with a limit of 5 bytes, then prints the limit. ```rust use std::io; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let f = File::open("foo.txt")?; // read at most five bytes let handle = f.take(5); println!("limit: {}", handle.limit()); Ok(()) } ``` -------------------------------- ### Basic HashMap operations Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashMap.html Shows creating a HashMap, inserting reviews, checking for a key, removing a key, looking up values, indexing, and iterating. Demonstrates type inference and querying with references. ```rust use std::collections::HashMap; // Type inference lets us omit an explicit type signature (which // would be `HashMap` in this example). let mut book_reviews = HashMap::new(); // Review some books. book_reviews.insert( "Adventures of Huckleberry Finn".to_string(), "My favorite book.".to_string(), ); book_reviews.insert( "Grimms' Fairy Tales".to_string(), "Masterpiece.".to_string(), ); book_reviews.insert( "Pride and Prejudice".to_string(), "Very enjoyable.".to_string(), ); book_reviews.insert( "The Adventures of Sherlock Holmes".to_string(), "Eye lyked it alot.".to_string(), ); // Check for a specific one. // When collections store owned values (String), they can still be // queried using references (&str). if !book_reviews.contains_key("Les Misérables") { println!("We've got {} reviews, but Les Misérables ain't one.", book_reviews.len()); } // oops, this review has a lot of spelling mistakes, let's delete it. book_reviews.remove("The Adventures of Sherlock Holmes"); // Look up the values associated with some keys. let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"]; for &book in &to_find { match book_reviews.get(book) { Some(review) => println!("{book}: {review}"), None => println!("{book} is unreviewed.") } } // Look up the value for a key (will panic if the key is not found). println!("Review for Jane: {}", book_reviews["Pride and Prejudice"]); // Iterate over everything. for (book, review) in &book_reviews { println!("{book}: \"{review}\""); } ``` -------------------------------- ### unwrap_err() success example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/type.Result.html Demonstrates successful use of unwrap_err to get the contained Err value from a Result. ```rust let x: Result = Err("emergency failure"); assert_eq!(x.unwrap_err(), "emergency failure"); ``` -------------------------------- ### get_disjoint_mut example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashMap.html Demonstrates using get_disjoint_mut to get mutable references to multiple values at once. Note that duplicate keys will cause a panic. ```rust use std::collections::HashMap; let mut libraries = HashMap::new(); libraries.insert("Athenæum".to_string(), 1807); // Duplicate keys panic! let got = libraries.get_disjoint_mut([ "Athenæum", "Athenæum", ]); ``` -------------------------------- ### Recovering writer with IntoInnerError::into_inner Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.IntoInnerError.html Example for `IntoInnerError::into_inner`: recovers the underlying writer from the error and then calls `into_inner()` again to get the `TcpStream`. ```rust use std::io::BufWriter; use std::net::TcpStream; let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); // do stuff with the stream // we want to get our `TcpStream` back, so let's try: let stream = match stream.into_inner() { Ok(s) => s, Err(e) => { // Here, e is an IntoInnerError, let's re-examine the buffer: let buffer = e.into_inner(); // do stuff to try to recover // afterwards, let's just return the stream buffer.into_inner().unwrap() } }; ``` -------------------------------- ### len: get number of elements in HashSet Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashSet.html Returns the number of elements in the set. The example shows that len() is 0 after creation and 1 after inserting one element. ```rust use std::collections::HashSet; let mut v = HashSet::new(); assert_eq!(v.len(), 0); v.insert(1); assert_eq!(v.len(), 1); ``` -------------------------------- ### Using BufReader to read a file line by line Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.BufRead.html Demonstrates converting a `File` (which implements `Read` but not `BufRead`) into a `BufReader` to enable line iteration. The example reads from `foo.txt` and prints each line. ```rust use std::io::{self, BufReader}; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let f = File::open("foo.txt")?; let f = BufReader::new(f); for line in f.lines() { let line = line?; println!("{line}"); } Ok(()) } ``` -------------------------------- ### write_fmt example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.Write.html Demonstrates the `write_fmt` method, which writes a formatted string using `format_args!`. It is primarily used by the `write!` macro, which is favored over calling `write_fmt` directly. Internally uses `write_all` and returns any I/O error encountered during formatting. ```rust use std::io::prelude::*; use std::fs::File; fn main() -> std::io::Result<()> { let mut buffer = File::create("foo.txt")?; // this call write!(buffer, "{:.*}", 2, 1.234567)?; // turns into this: buffer.write_fmt(format_args!("{:.*}", 2, 1.234567))?; Ok(()) } ``` -------------------------------- ### Get buffer capacity with BufReader::capacity Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.BufReader.html Returns the number of bytes the internal buffer can hold at once. The example asserts that the filled buffer length does not exceed the capacity. ```rust use std::io::{BufReader, BufRead}; use std::fs::File; fn main() -> std::io::Result<()> { let f = File::open("log.txt")?; let mut reader = BufReader::new(f); let capacity = reader.capacity(); let buffer = reader.fill_buf()?; assert!(buffer.len() <= capacity); Ok(()) } ``` -------------------------------- ### hasher: Get reference to HashSet's BuildHasher Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashSet.html Returns a reference to the set's BuildHasher. This example creates a HashSet with a custom RandomState and retrieves the hasher reference. ```rust use std::collections::HashSet; use std::hash::RandomState; let hasher = RandomState::new(); let set: HashSet = HashSet::with_hasher(hasher); let hasher: &RandomState = set.hasher(); ``` -------------------------------- ### Get cursor position with position Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.Cursor.html Returns the current position of the cursor. The example shows how position changes after seeking relative to the current position using SeekFrom::Current. ```rust use std::io::Cursor; use std::io::prelude::*; use std::io::SeekFrom; let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); assert_eq!(buff.position(), 0); buff.seek(SeekFrom::Current(2)).unwrap(); assert_eq!(buff.position(), 2); buff.seek(SeekFrom::Current(-1)).unwrap(); assert_eq!(buff.position(), 1); ``` -------------------------------- ### Initialize HashMap from an array Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashMap.html Shows how to create a HashMap with a known list of items using HashMap::from with an array of key-value pairs. ```rust use std::collections::HashMap; let solar_distance = HashMap::from([ ("Mercury", 0.4), ("Venus", 0.7), ("Earth", 1.0), ("Mars", 1.5), ]); ``` -------------------------------- ### fn take(self, limit: u64) -> Take Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/trait.Read.html Creates an adapter that limits the number of bytes read from this reader to a specified maximum. ```APIDOC ## fn take(self, limit: u64) -> Take ⓘ ### Description Creates an adapter which will read at most `limit` bytes from it. This function returns a new instance of `Read` which will read at most `limit` bytes, after which it will always return EOF (`Ok(0)`). Any read errors will not count towards the number of bytes read and future calls to `read()` may succeed. ### Method take ### Parameters - **limit** (u64) - Required - The maximum number of bytes to read. ### Return Value - **Take** - A new `Read` instance that reads at most `limit` bytes. ### Example ```rust use std::io; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let f = File::open("foo.txt")?; let mut buffer = [0; 5]; // read at most five bytes let mut handle = f.take(5); handle.read(&mut buffer)?; Ok(()) } ``` ``` -------------------------------- ### into_err() example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/type.Result.html Shows how to use into_err to get the contained Err value without panicking. This is a nightly-only experimental API that fails to compile if the ok type can actually occur. ```rust fn only_bad_news() -> Result { Err("Oops, it failed".into()) } let error: String = only_bad_news().into_err(); println!("{error}"); ``` -------------------------------- ### Building BitcoinNodeHash from a string Source: https://docs.rs/rustreexo/latest/rustreexo/node_hash/index.html Demonstrates how to create a BitcoinNodeHash instance from a hexadecimal string using FromStr. ```rust use std::str::FromStr; use rustreexo::node_hash::BitcoinNodeHash; let hash = BitcoinNodeHash::from_str( "0000000000000000000000000000000000000000000000000000000000000000", ) .unwrap(); assert_eq!( hash.to_string().as_str(), "0000000000000000000000000000000000000000000000000000000000000000" ); ``` -------------------------------- ### capacity: get number of elements without reallocating Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashSet.html Returns the number of elements the set can hold without reallocating. The example creates a set with capacity 100 and asserts the capacity is at least 100. ```rust use std::collections::HashSet; let set: HashSet = HashSet::with_capacity(100); assert!(set.capacity() >= 100); ``` -------------------------------- ### Building BitcoinNodeHash from a slice Source: https://docs.rs/rustreexo/latest/rustreexo/node_hash/index.html Shows how to initialize a BitcoinNodeHash using a 32-byte array via the new constructor or the From trait. ```rust use std::str::FromStr; use rustreexo::node_hash::BitcoinNodeHash; let hash1 = BitcoinNodeHash::new([0; 32]); // ... or ... let hash2 = BitcoinNodeHash::from([0; 32]); assert_eq!(hash1, hash2); assert_eq!( hash1.to_string().as_str(), "0000000000000000000000000000000000000000000000000000000000000000" ); ``` -------------------------------- ### get_disjoint_unchecked_mut example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashMap.html Demonstrates using get_disjoint_unchecked_mut to get mutable references to multiple values without validating uniqueness. Overlapping keys are undefined behavior, so the keys must be unique. Missing keys result in None. ```rust use std::collections::HashMap; let mut libraries = HashMap::new(); libraries.insert("Bodleian Library".to_string(), 1602); libraries.insert("Athenæum".to_string(), 1807); libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691); libraries.insert("Library of Congress".to_string(), 1800); // SAFETY: The keys do not overlap. let [Some(a), Some(b)] = (unsafe { libraries.get_disjoint_unchecked_mut([ "Athenæum", "Bodleian Library", ]) }) else { panic!() }; // SAFETY: The keys do not overlap. let got = unsafe { libraries.get_disjoint_unchecked_mut([ "Athenæum", "Library of Congress", ]) }; assert_eq!( got, [ Some(&mut 1807), Some(&mut 1800), ], ); // SAFETY: The keys do not overlap. let got = unsafe { libraries.get_disjoint_unchecked_mut([ "Athenæum", "New York Public Library", ]) }; // Missing keys result in None assert_eq!(got, [Some(&mut 1807), None]); ``` -------------------------------- ### Import I/O prelude with use std::io::prelude::* Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/index.html Add this glob import to the top of I/O-heavy modules to bring common I/O traits (BufRead, Read, Seek, Write) into scope. ```rust use std::io::prelude::*; ``` -------------------------------- ### Generate and Verify MemForest Proof Source: https://docs.rs/rustreexo/latest/src/rustreexo/mem_forest/mod.rs.html Demonstrates how to initialize a MemForest, modify it with hashes, generate a proof for specific elements, and verify the proof against the forest. ```rust let del_hashes = [hashes[2], hashes[1], hashes[4], hashes[6]]; let mut p = MemForest::new(); p.modify(&hashes, &[]).expect("Test mem_forests are valid"); let proof = p.prove(&del_hashes).expect("Should be able to prove"); let expected_proof = Proof::new( [2, 1, 4, 6].to_vec(), vec![ "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d" .parse() .unwrap(), "084fed08b978af4d7d196a7446a86b58009e636b611db16211b65a9aadff29c5" .parse() .unwrap(), "e77b9a9ae9e30b0dbdb6f510a264ef9de781501d7b6b92ae89eb059c5ab743db" .parse() .unwrap(), "ca358758f6d27e6cf45272937977a748fd88391db679ceda7dc7bf1f005ee879" .parse() .unwrap(), ], ); assert_eq!(proof, expected_proof); assert!(p.verify(&proof, &del_hashes).unwrap()); } ``` -------------------------------- ### fn take(self, limit: u64) -> Take Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.Read.html Creates an adapter that limits the number of bytes read from this stream to a specified maximum. ```APIDOC ## fn take(self, limit: u64) -> Take ⓘ ### Description Creates an adapter which will read at most `limit` bytes from it. This function returns a new instance of `Read` which will read at most `limit` bytes, after which it will always return EOF (`Ok(0)`). Any read errors will not count towards the number of bytes read and future calls to `read()` may succeed. ### Method take ### Signature `fn take(self, limit: u64) -> Take where Self: Sized` ### Parameters - **limit** (u64) - Required - The maximum number of bytes to read. ### Returns - **Take** - An adapter that limits the number of bytes read. ### Example ```rust use std::io; use std::io::prelude::*; use std::fs::File; fn main() -> io::Result<()> { let f = File::open("foo.txt")?; let mut buffer = [0; 5]; // read at most five bytes let mut handle = f.take(5); handle.read(&mut buffer)?; Ok(()) } ``` ``` -------------------------------- ### insert example Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashMap.html Demonstrates using insert to add a key-value pair to the map. If the key already exists, the value is updated and the old value is returned. ```rust use std::collections::HashMap; let mut map = HashMap::new(); assert_eq!(map.insert(37, "a"), None); assert_eq!(map.is_empty(), false); map.insert(37, "b"); assert_eq!(map.insert(37, "c"), Some("b")); assert_eq!(map[&37], "c"); ``` -------------------------------- ### Get immutable reference with get_ref Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.Cursor.html Gets an immutable reference to the underlying value in the cursor. Use this to inspect the buffer without consuming the cursor. ```rust use std::io::Cursor; let buff = Cursor::new(Vec::new()); let reference = buff.get_ref(); ``` -------------------------------- ### Create and verify a Proof with rustreexo Source: https://docs.rs/rustreexo/latest/rustreexo/proof/index.html Creates a new accumulator, adds eight leaf hashes, builds a proof for leaf 0, and verifies it. Requires the bitcoin_hashes crate for SHA-256 hashing and the rustreexo types. The proof hashes are hard-coded from the example; the final assert expects verification to succeed. ```rust use std::str::FromStr; use bitcoin_hashes::sha256; use bitcoin_hashes::Hash; use bitcoin_hashes::HashEngine; use rustreexo::node_hash::BitcoinNodeHash; use rustreexo::proof::Proof; use rustreexo::stump::Stump; let s = Stump::new(); // Creates a tree with those values as leaves let test_values: Vec = vec![0, 1, 2, 3, 4, 5, 6, 7]; // Targets are the nodes we intend to prove let targets = vec![0]; // The hashes used to prove an element. let mut proof_hashes = Vec::new(); proof_hashes.push( BitcoinNodeHash::from_str( "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a", ) .unwrap(), ); proof_hashes.push( BitcoinNodeHash::from_str( "9576f4ade6e9bc3a6458b506ce3e4e890df29cb14cb5d3d887672aef55647a2b", ) .unwrap(), ); proof_hashes.push( BitcoinNodeHash::from_str( "29590a14c1b09384b94a2c0e94bf821ca75b62eacebc47893397ca88e3bbcbd7", ) .unwrap(), ); // Hashes of the leaves UTXOs we'll add to the accumulator let mut hashes = Vec::new(); for i in test_values { let mut engine = sha256::Hash::engine(); engine.input(&[i]); hashes.push(sha256::Hash::from_engine(engine).into()) } // Add the UTXOs to the accumulator let s = s.modify(&hashes, &vec![], &Proof::default()).unwrap().0; // Create a proof for the targets let p = Proof::new(targets, proof_hashes); // Verify the proof assert!(s.verify(&p, &vec![hashes[0]]).expect("This proof is valid")); ``` -------------------------------- ### Get mutable reference to underlying writer with get_mut Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/struct.BufWriter.html Gets a mutable reference to the underlying writer. Directly writing to the underlying writer is inadvisable. ```rust use std::io::BufWriter; use std::net::TcpStream; let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); // we can use reference just like buffer let reference = buffer.get_mut(); ``` -------------------------------- ### Create a HashMap with capacity, hasher, and allocator using with_capacity_and_hasher_in Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/struct.HashMap.html Initializes an empty HashMap with a specified capacity, custom hash builder, and allocator. This is a nightly-only experimental API. ```rust #![feature(allocator_api)] use std::alloc::Global; use std::collections::HashMap; use std::hash::RandomState; let s = RandomState::new(); let map: HashMap = HashMap::with_capacity_and_hasher_in(10, s, Global); ``` -------------------------------- ### has_data_left example: reading lines until EOF Source: https://docs.rs/rustreexo/latest/rustreexo/prelude/io/prelude/trait.BufRead.html Example for the nightly-only has_data_left method, showing how to loop while data is available, reading lines from stdin. ```rust #![feature(buf_read_has_data_left)] use std::io; use std::io::prelude::*; let stdin = io::stdin(); let mut stdin = stdin.lock(); while stdin.has_data_left()? { let mut line = String::new(); stdin.read_line(&mut line)?; // work with line println!("{line:?}"); } ```