### Creating an Example for a Documented Function Source: https://docs.rs/negentropy/latest/scrape-examples-help.html Write an example in your project's examples directory that calls the documented function. This example will be scraped by Rustdoc. ```rust // examples/ex.rs fn main() { a_crate::a_func(); } ``` -------------------------------- ### Negentropy Client and Relay Example Source: https://docs.rs/negentropy/latest/src/negentropy/negentropy.rs.html Demonstrates the initialization and reconciliation process using the Negentropy crate. This example shows how to set up both a client and a relay with their respective storage and IDs, then perform the reconciliation steps. ```Rust 1// Copyright (c) 2023 Yuki Kishimoto 2// Distributed under the MIT software license 3 4use negentropy::{Id, Negentropy, NegentropyStorageVector}; 5 6fn main() { 7 // Client 8 let mut storage_client = NegentropyStorageVector::new(); 9 storage_client 10 .insert( 11 0, 12 Id::from_slice(b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), 13 ) 14 .unwrap(); 15 storage_client 16 .insert( 17 1, 18 Id::from_slice(b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb").unwrap(), 19 ) 20 .unwrap(); 21 storage_client.seal().unwrap(); 22 let mut client = Negentropy::borrowed(&storage_client, 0).unwrap(); 23 let init_output = client.initiate().unwrap(); 24 println!("Initiator Output: {:x?}", init_output.clone()); 25 26 // Relay 27 let mut storage_relay = NegentropyStorageVector::new(); 28 storage_relay 29 .insert( 30 0, 31 Id::from_slice(b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), 32 ) 33 .unwrap(); 34 storage_relay 35 .insert( 36 2, 37 Id::from_slice(b"cccccccccccccccccccccccccccccccc").unwrap(), 38 ) 39 .unwrap(); 40 storage_relay 41 .insert( 42 3, 43 Id::from_slice(b"11111111111111111111111111111111").unwrap(), 44 ) 45 .unwrap(); 46 storage_relay 47 .insert( 48 5, 49 Id::from_slice(b"22222222222222222222222222222222").unwrap(), 50 ) 51 .unwrap(); 52 storage_relay 53 .insert( 54 10, 55 Id::from_slice(b"33333333333333333333333333333333").unwrap(), 56 ) 57 .unwrap(); 58 storage_relay.seal().unwrap(); 59 let mut relay = Negentropy::borrowed(&storage_relay, 0).unwrap(); 60 let reconcile_output = relay.reconcile(&init_output).unwrap(); 61 println!("Reconcile Output: {:x?}", reconcile_output.clone()); 62 63 // Client 64 let mut have_ids = Vec::new(); 65 let mut need_ids = Vec::new(); 66 client 67 .reconcile_with_ids(&reconcile_output, &mut have_ids, &mut need_ids) 68 .unwrap(); 69 println!( 70 "Have IDs: " 71 .into_iter() 72 .map(|b| format!("{:x?}", b)) 73 .collect::>() 74 .join("") 75 ); 76 println!( 77 "Need IDs: " 78 .into_iter() 79 .map(|b| format!("{:x?}", b)) 80 .collect::>() 81 .join("") 82 ); 83} ``` -------------------------------- ### Documenting a Public Function in Rust Source: https://docs.rs/negentropy/latest/scrape-examples-help.html Define a public function in your library's source code that you want to document and provide examples for. ```rust // src/lib.rs pub fn a_func() {} ``` -------------------------------- ### Get Item by Index Source: https://docs.rs/negentropy/latest/negentropy/trait.NegentropyStorageBase.html The `get_item` method retrieves an item from storage at a specific index. It returns an `Option` which will be `None` if the index is out of bounds. ```rust fn get_item(&self, i: usize) -> Result, Error>; ``` -------------------------------- ### Implement Default for Bound Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Provides a default value for the Bound struct. Use `default()` to get a Bound instance with its default field values. ```rust fn default() -> Bound ``` -------------------------------- ### Get Size of Storage Source: https://docs.rs/negentropy/latest/negentropy/trait.NegentropyStorageBase.html The `size` method returns the total number of items currently stored. It is a required method for any type implementing NegentropyStorageBase. ```rust fn size(&self) -> Result; ``` -------------------------------- ### NegentropyStorageVector Implementation of NegentropyStorageBase - Size and Get Item Source: https://docs.rs/negentropy/latest/src/negentropy/storage.rs.html Implements the `size` and `get_item` methods from the `NegentropyStorageBase` trait for `NegentropyStorageVector`. These operations require the storage to be sealed. ```rust impl NegentropyStorageBase for NegentropyStorageVector { fn size(&self) -> Result { self.check_sealed()?; Ok(self.items.len()) } fn get_item(&self, i: usize) -> Result, Error> { self.check_sealed()?; Ok(self.items.get(i).copied()) } // ... other methods ``` -------------------------------- ### Implement CloneToUninit (Nightly) Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html An experimental nightly-only feature for cloning data into uninitialized memory. Use with caution as it is unsafe. ```rust unsafe fn clone_to_uninit(&self, dest: *mut u8) ``` -------------------------------- ### Access Fingerprint buffer Source: https://docs.rs/negentropy/latest/src/negentropy/types.rs.html Provides a method to get the underlying byte array of a Fingerprint. ```rust impl Fingerprint { #[inline] pub fn to_bytes(self) -> [u8; FINGERPRINT_SIZE] { self.buf } } ``` -------------------------------- ### NegentropyStorageVector Constructor Methods Source: https://docs.rs/negentropy/latest/src/negentropy/storage.rs.html Provides methods to create new instances of `NegentropyStorageVector`. `new()` creates a default empty storage, while `with_capacity()` pre-allocates space for a given number of items. ```rust impl NegentropyStorageVector { /// Create new storage #[inline] pub fn new() -> Self { Self::default() } /// Create new storage with capacity #[inline] pub fn with_capacity(capacity: usize) -> Self { Self { items: Vec::with_capacity(capacity), sealed: false, } } // ... other methods ``` -------------------------------- ### Get Item ID Source: https://docs.rs/negentropy/latest/negentropy/struct.Item.html Retrieves a reference to the Id of the Item. This is a simple getter method. ```rust pub fn get_id(&self) -> &Id ``` -------------------------------- ### Initiate and Reconcile Flow Source: https://docs.rs/negentropy/latest/negentropy/struct.Negentropy.html Demonstrates the typical flow of using the Negentropy protocol as both a client (initiator) and a relay. ```APIDOC ## Negentropy Protocol Example ### Description This example showcases the Negentropy protocol's client-side initiation and the relay's reconciliation process. ### Client Initiation 1. A `NegentropyStorageVector` is created and populated with data. 2. The storage is sealed. 3. A `Negentropy` client instance is created using the storage. 4. The `initiate()` method is called to generate an initial message. ### Relay Reconciliation 1. A `NegentropyStorageVector` is created for the relay and populated with its data. 2. The storage is sealed. 3. A `Negentropy` relay instance is created. 4. The `reconcile()` method is called with the output from the client's `initiate()` method. ### Client Reconciliation with IDs 1. The client uses the output from the relay's `reconcile()` method. 2. The `reconcile_with_ids()` method is called to determine which IDs the client has and which it needs. ### Code Example ```rust fn main() { // Client let mut storage_client = NegentropyStorageVector::new(); storage_client .insert( 0, Id::from_slice(b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), ) .unwrap(); storage_client .insert( 1, Id::from_slice(b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb").unwrap(), ) .unwrap(); storage_client.seal().unwrap(); let mut client = Negentropy::borrowed(&storage_client, 0).unwrap(); let init_output = client.initiate().unwrap(); println!("Initiator Output: {:x?}", init_output.clone()); // Relay let mut storage_relay = NegentropyStorageVector::new(); storage_relay .insert( 0, Id::from_slice(b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), ) .unwrap(); storage_relay .insert( 2, Id::from_slice(b"cccccccccccccccccccccccccccccccc").unwrap(), ) .unwrap(); storage_relay .insert( 3, Id::from_slice(b"11111111111111111111111111111111").unwrap(), ) .unwrap(); storage_relay .insert( 5, Id::from_slice(b"22222222222222222222222222222222").unwrap(), ) .unwrap(); storage_relay .insert( 10, Id::from_slice(b"33333333333333333333333333333333").unwrap(), ) .unwrap(); storage_relay.seal().unwrap(); let mut relay = Negentropy::borrowed(&storage_relay, 0).unwrap(); let reconcile_output = relay.reconcile(&init_output).unwrap(); println!("Reconcile Output: {:x?}", reconcile_output.clone()); // Client let mut have_ids = Vec::new(); let mut need_ids = Vec::new(); client .reconcile_with_ids(&reconcile_output, &mut have_ids, &mut need_ids) .unwrap(); println!( "Have IDs: {}", have_ids .into_iter() .map(|b| format!("{:x?}", b)) .collect::>() .join("") ); println!( "Need IDs: {}", need_ids .into_iter() .map(|b| format!("{:x?}", b)) .collect::>() .join("") ); } ``` ``` -------------------------------- ### Negentropy Initialization Source: https://docs.rs/negentropy/latest/negentropy/struct.Negentropy.html Methods for creating new Negentropy instances with different storage and ownership options. ```APIDOC ## Negentropy Struct ### Description Represents a Negentropy instance used for data reconciliation. ## Implementations ### `impl<'a, T> Negentropy<'a, T>` #### `pub fn new(storage: Storage<'a, T>, frame_size_limit: u64) -> Result` ##### Description Create a new `Negentropy` instance using a borrowed storage. ##### Parameters - **storage** (Storage<'a, T>) - The storage to use for Negentropy operations. - **frame_size_limit** (u64) - The frame size limit. Must be equal to 0 or greater than 4096. ##### Returns A `Result` containing the new `Negentropy` instance or an `Error`. #### `pub fn owned(storage: T, frame_size_limit: u64) -> Result` ##### Description Create a new `Negentropy` instance from owned storage. ##### Parameters - **storage** (T) - The owned storage to use for Negentropy operations. - **frame_size_limit** (u64) - The frame size limit. Must be equal to 0 or greater than 4096. ##### Returns A `Result` containing the new `Negentropy` instance or an `Error`. #### `pub fn borrowed(storage: &'a T, frame_size_limit: u64) -> Result` ##### Description Create a new `Negentropy` instance from borrowed storage. ##### Parameters - **storage** (&'a T) - The borrowed storage to use for Negentropy operations. - **frame_size_limit** (u64) - The frame size limit. Must be equal to 0 or greater than 4096. ##### Returns A `Result` containing the new `Negentropy` instance or an `Error`. ##### Example ```rust // Client let mut storage_client = NegentropyStorageVector::new(); storage_client .insert( 0, Id::from_slice(b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), ) .unwrap(); storage_client .insert( 1, Id::from_slice(b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb").unwrap(), ) .unwrap(); storage_client.seal().unwrap(); let mut client = Negentropy::borrowed(&storage_client, 0).unwrap(); ``` ``` -------------------------------- ### Create NegentropyStorageVector Source: https://docs.rs/negentropy/latest/negentropy/struct.NegentropyStorageVector.html Initializes a new instance of NegentropyStorageVector. This is often the first step before inserting data. ```rust let mut storage_client = NegentropyStorageVector::new(); ``` -------------------------------- ### Item Constructors Source: https://docs.rs/negentropy/latest/negentropy/struct.Item.html Provides methods for creating new Item instances. ```APIDOC ## Item Constructors ### `pub fn new() -> Self` Creates a new Item with default values. ### `pub fn with_timestamp(timestamp: u64) -> Self` Creates a new Item with a specified timestamp and a default ID (0s). ### `pub fn with_timestamp_and_id(timestamp: u64, id: Id) -> Self` Creates a new Item with both a specified timestamp and ID. ``` -------------------------------- ### Id Struct and Methods Source: https://docs.rs/negentropy/latest/src/negentropy/id.rs.html Documentation for the `Id` struct, its constructors, and utility methods. ```APIDOC ## Id Struct ### Description Represents a unique identifier, typically a 32-byte array. ### Fields - **`[u8; ID_SIZE]`**: The inner byte array representing the ID. ### Methods #### `new(bytes: [u8; ID_SIZE]) -> Self` * **Description**: Constructs an `Id` from a byte array. This method is deprecated. * **Deprecated**: `since = "1.0.0", note = "Use `from_byte_array` instead"` #### `from_byte_array(bytes: [u8; Self::LEN]) -> Self` * **Description**: Constructs an `Id` from a 32-byte array. * **Parameters**: - **bytes** (`[u8; Self::LEN]`) - The 32-byte array to construct the ID from. #### `from_slice(slice: &[u8]) -> Result` * **Description**: Constructs an `Id` from a byte slice. * **Parameters**: - **slice** (`&[u8]`) - The byte slice to construct the ID from. * **Returns**: `Ok(Self)` if the slice has the correct length, `Err(Error::InvalidIdSize)` otherwise. #### `to_bytes(self) -> [u8; Self::LEN]` * **Description**: Returns the inner byte array of the `Id`. * **Returns**: `[u8; Self::LEN]` - The byte array. #### `as_bytes(&self) -> &[u8; Self::LEN]` * **Description**: Returns a reference to the inner byte array of the `Id`. * **Returns**: `&[u8; Self::LEN]` - A reference to the byte array. ### Traits #### `Deref` Allows the `Id` struct to be treated as a slice of bytes (`&[u8; Self::LEN]`). #### `DerefMut` Allows mutable access to the inner byte array of the `Id` (`&mut [u8; Self::LEN]`). ``` -------------------------------- ### Get Bytes from Slice Source: https://docs.rs/negentropy/latest/src/negentropy/encoding.rs.html Extracts a specified number of bytes from the beginning of a mutable byte slice and advances the slice. Returns an error if the slice is too short. ```Rust pub fn get_bytes<'a>(encoded: &'a mut &[u8], n: usize) -> Result<&'a [u8], Error> { if encoded.len() < n { return Err(Error::ParseEndsPrematurely); } let res: &[u8] = &encoded[..n]; *encoded = encoded.get(n..).unwrap_or_default(); Ok(res) } ``` -------------------------------- ### SHA-256 Test Cases in Rust Source: https://docs.rs/negentropy/latest/src/negentropy/sha256.rs.html Contains test cases for the SHA-256 implementation, including expected hash outputs for various inputs like "Bitcoin: A Peer-to-Peer Electronic Cash System", an empty string, and "Hello, world!". ```Rust #[cfg(test)] mod tests { use super::*; const HASHES: [(&str, [u8; 32]); 10] = [ ("Bitcoin: A Peer-to-Peer Electronic Cash System", [0xef, 0xb5, 0xc6, 0x72, 0x9d, 0x8c, 0xe3, 0xe0, 0x3f, 0xd0, 0x3a, 0xec, 0x34, 0x05, 0x40, 0xb2, 0x4a, 0x78, 0x84, 0x54, 0xd4, 0x5e, 0x71, 0x70, 0x89, 0xb1, 0xe5, 0x92, 0x43, 0xe1, 0x6f, 0x43] ), ("", [ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 ] ), ("Hello, world!", [ 0x31, 0x5f, 0x5b, 0xdb, 0x76, 0xd0, 0x78, 0xc4, 0x3b, 0x8a, 0xc0, 0x06, 0x4e, 0x4a, 0x01, 0x64, ``` -------------------------------- ### From and Into Trait Implementations Source: https://docs.rs/negentropy/latest/negentropy/struct.Item.html Implements the `From` for `T` and `Into` for `T` traits. `From` provides a way to create a type from another, and `Into` provides a convenient way to perform conversions when `From` is implemented. ```rust impl From for T ``` ```rust fn from(t: T) -> T ``` ```rust impl Into for T where U: From, ``` ```rust fn into(self) -> U ``` -------------------------------- ### Get Fixed-Size Byte Array Source: https://docs.rs/negentropy/latest/src/negentropy/encoding.rs.html Retrieves a byte array of a specified size from a mutable byte slice. Ensures the slice has sufficient length before attempting to extract. ```Rust pub fn get_byte_array(encoded: &mut &[u8]) -> Result<[u8; N], Error> { Ok(get_bytes(encoded, N)?.try_into()?) } ``` -------------------------------- ### Item Methods Source: https://docs.rs/negentropy/latest/negentropy/struct.Item.html Methods available for interacting with Item instances. ```APIDOC ## Item Methods ### `pub fn get_id(&self) -> &Id` Retrieves a reference to the item's ID. ``` -------------------------------- ### Encode Bound in Rust Source: https://docs.rs/negentropy/latest/src/negentropy/lib.rs.html Initializes a byte vector for encoding a `Bound` object. This function is a starting point and likely calls other encoding functions for timestamp and ID. ```rust fn encode_bound(&mut self, bound: &Bound) -> Vec { let mut output: Vec = Vec::new(); ``` -------------------------------- ### NegentropyStorageBase Trait Definition Source: https://docs.rs/negentropy/latest/src/negentropy/storage.rs.html Defines the core interface for storage implementations in Negentropy. It includes methods for getting the size, retrieving items, iterating over items, and finding lower bounds. ```rust pub trait NegentropyStorageBase { /// Size fn size(&self) -> Result; /// Get Item fn get_item(&self, i: usize) -> Result, Error>; /// Iterate fn iterate( &self, begin: usize, end: usize, cb: &mut dyn FnMut(Item, usize) -> Result, ) -> Result<(), Error>; /// Find Lower Bound fn find_lower_bound(&self, first: usize, last: usize, value: &Bound) -> usize; /// Fingerprint fn fingerprint(&self, begin: usize, end: usize) -> Result { let mut out = Accumulator::new(); self.iterate(begin, end, &mut |item: Item, _| { out.add(&item.id)?; Ok(true) })?; out.get_fingerprint((end - begin) as u64) } } ``` -------------------------------- ### Bound Constructor Methods Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Provides methods for creating new instances of the Bound struct. ```APIDOC ## Implementations for Bound ### `impl Bound` #### `pub fn new() -> Self` **Description**: Creates a new, default Bound instance. #### `pub fn from_item(item: &Item) -> Self` **Description**: Creates a new Bound instance from a given Item. #### `pub fn with_timestamp(timestamp: u64) -> Self` **Description**: Creates a new Bound instance using a timestamp. The ID length is initialized to 0. #### `pub fn with_timestamp_and_id(timestamp: u64, id: T) -> Result` where T: AsRef<[u8]> **Description**: Creates a new Bound instance from a timestamp and an ID. Returns a Result indicating success or an Error. ``` -------------------------------- ### Implement PartialEq for Bound Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Allows equality checks between Bound instances. The `eq()` method tests for equality, while `ne()` tests for inequality. ```rust fn eq(&self, other: &Bound) -> bool ``` ```rust fn ne(&self, other: &Rhs) -> bool ``` -------------------------------- ### Get Minimal Bound for Negentropy Source: https://docs.rs/negentropy/latest/src/negentropy/lib.rs.html Determines the minimal bound between two items based on their timestamps and IDs. If timestamps differ, it uses the current item's timestamp. Otherwise, it calculates the shared prefix of their IDs. ```rust fn get_minimal_bound(&self, prev: &Item, curr: &Item) -> Result { if curr.timestamp != prev.timestamp { Ok(Bound::with_timestamp(curr.timestamp)) } else { let mut shared_prefix_bytes: usize = 0; let curr_key = curr.id; let prev_key = prev.id; for i in 0..ID_SIZE { if curr_key[i] != prev_key[i] { break; } shared_prefix_bytes += 1; } Ok(Bound::with_timestamp_and_id( curr.timestamp, &curr_key[..shared_prefix_bytes + 1], )?) } } ``` -------------------------------- ### Create Negentropy Instance from Owned Storage Source: https://docs.rs/negentropy/latest/negentropy/struct.Negentropy.html Constructs a new Negentropy instance from owned storage. The frame size limit must be 0 or greater than 4096. ```rust pub fn owned(storage: T, frame_size_limit: u64) -> Result ``` -------------------------------- ### Create new Accumulator Source: https://docs.rs/negentropy/latest/src/negentropy/types.rs.html Initializes a new Accumulator with all bytes set to zero. ```rust impl Accumulator { /// New Accumulator pub fn new() -> Self { Self { buf: [0; ID_SIZE] } } /// Add pub fn add(&mut self, buf: &[u8; ID_SIZE]) -> Result<(), Error> { let mut curr_carry = Wrapping(0u64); let mut next_carry = Wrapping(0u64); let p = &self.buf[..]; let po = buf; let mut wtr = Vec::with_capacity(ID_SIZE); for i in 0..4 { ``` -------------------------------- ### Create New Bound Instance Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Provides methods to create new instances of the Bound struct. Use `new()` for a default instance, `from_item()` with an existing item, or `with_timestamp()` for a timestamp-based bound with no ID. ```rust pub fn new() -> Self ``` ```rust pub fn from_item(item: &Item) -> Self ``` ```rust pub fn with_timestamp(timestamp: u64) -> Self ``` -------------------------------- ### Implement Clone for Bound Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Allows creating deep copies of Bound instances. The `clone()` method returns a duplicate, while `clone_from()` performs assignment from another Bound instance. ```rust fn clone(&self) -> Bound ``` ```rust fn clone_from(&mut self, source: &Self) ``` -------------------------------- ### Initialize Negentropy Instance Source: https://docs.rs/negentropy/latest/src/negentropy/lib.rs.html Creates a new `Negentropy` instance. The `frame_size_limit` must be 0 or greater than 4096. This is used for setting up the reconciliation process. ```rust pub fn new(storage: Storage<'a, T>, frame_size_limit: u64) -> Result { if frame_size_limit != 0 && frame_size_limit < 4096 { return Err(Error::FrameSizeLimitTooSmall); } Ok(Self { storage, frame_size_limit, is_initiator: false, last_timestamp_in: 0, last_timestamp_out: 0, }) } ``` -------------------------------- ### Implement Copy and Eq for Bound Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Indicates that Bound instances can be copied bitwise and are guaranteed to have a total equality relation. ```rust impl Copy for Bound ``` ```rust impl Eq for Bound ``` -------------------------------- ### Id Comparison Methods Source: https://docs.rs/negentropy/latest/negentropy/struct.Id.html Methods for comparing Id instances for equality and ordering. ```APIDOC ## Id Comparison Methods ### `eq` Method Tests for `self` and `other` values to be equal, and is used by `==`. - **Version**: 1.0.0 ### `ne` Method Tests for `!=`. The default implementation is almost always sufficient, and should not be overridden without very good reason. ``` -------------------------------- ### Error Provide Trait Implementation (Nightly Experimental) Source: https://docs.rs/negentropy/latest/negentropy/enum.Error.html Implements the experimental `provide` method for the `Error` enum. This is a nightly-only API for type-based access to error report context. ```rust fn provide<'a>(&'a self, request: &mut Request<'a>) ``` -------------------------------- ### Implement PartialOrd for Bound Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Enables partial ordering comparisons for Bound instances. Supports methods like `partial_cmp()`, `lt()`, `le()`, `gt()`, and `ge()` for various comparison operators. ```rust fn partial_cmp(&self, other: &Self) -> Option ``` ```rust fn lt(&self, other: &Rhs) -> bool ``` ```rust fn le(&self, other: &Rhs) -> bool ``` ```rust fn gt(&self, other: &Rhs) -> bool ``` ```rust fn ge(&self, other: &Rhs) -> bool ``` -------------------------------- ### Create new Bound Source: https://docs.rs/negentropy/latest/src/negentropy/types.rs.html Provides methods to create new Bound instances, including default, from an item, with a timestamp, and with a timestamp and ID. ```rust impl Bound { /// New Bound #[inline] pub fn new() -> Self { Self::default() } /// new Bound from item pub fn from_item(item: &Item) -> Self { let mut bound = Self::new(); bound.item = *item; bound.id_len = ID_SIZE; bound } /// new Bound from timestamp, id len is 0 pub fn with_timestamp(timestamp: u64) -> Self { let mut bound = Self::new(); bound.item.timestamp = timestamp; bound.id_len = 0; bound } /// New Bound from timestamp and id pub fn with_timestamp_and_id(timestamp: u64, id: T) -> Result where T: AsRef<[u8]>, { let id: &[u8] = id.as_ref(); let len: usize = id.len(); if len > ID_SIZE { return Err(Error::IdTooBig); } let mut out = Bound::new(); out.item.timestamp = timestamp; out.item.id[..len].copy_from_slice(id); out.id_len = len; Ok(out) } } ``` -------------------------------- ### try_into Method Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Performs a conversion that may fail, returning a Result. ```APIDOC ## try_into Method ### Description Performs the conversion. This method attempts to convert the current value into another type `U`. If the conversion is successful, it returns `Ok(U)`. If the conversion fails, it returns `Err` with the appropriate error type. ### Method Signature ```rust fn try_into(self) -> Result>::Error>; ``` ### Parameters None (operates on `self`) ### Return Value A `Result` which is either `Ok(U)` on successful conversion or `Err(>::Error)` on failure. ``` -------------------------------- ### Create New Item Source: https://docs.rs/negentropy/latest/negentropy/struct.Item.html Constructs a new Item instance. The `new` function creates an item with default values, while `with_timestamp` and `with_timestamp_and_id` allow for specific initialization. ```rust pub fn new() -> Self ``` ```rust pub fn with_timestamp(timestamp: u64) -> Self ``` ```rust pub fn with_timestamp_and_id(timestamp: u64, id: Id) -> Self ``` -------------------------------- ### Create Negentropy Instance from Borrowed Storage Source: https://docs.rs/negentropy/latest/src/negentropy/lib.rs.html Creates a new `Negentropy` instance using borrowed storage. The `frame_size_limit` must be 0 or greater than 4096. ```rust pub fn borrowed(storage: &'a T, frame_size_limit: u64) -> Result { Self::new(Storage::Borrowed(storage), frame_size_limit) } ``` -------------------------------- ### Create New Negentropy Instance Source: https://docs.rs/negentropy/latest/negentropy/struct.Negentropy.html Constructs a new Negentropy instance using provided storage. The frame size limit must be 0 or greater than 4096. ```rust pub fn new( storage: Storage<'a, T>, frame_size_limit: u64, ) -> Result ``` -------------------------------- ### Perform 256-bit Addition with Carry Source: https://docs.rs/negentropy/latest/src/negentropy/types.rs.html This snippet demonstrates a 256-bit addition operation with carry propagation, essential for cryptographic algorithms that require arbitrary-precision arithmetic. It processes data in 64-bit chunks. ```rust let orig = Wrapping(u64::from_le_bytes(p[(i * 8)..(i * 8 + 8)].try_into()?)); let other_v = Wrapping(u64::from_le_bytes(po[(i * 8)..(i * 8 + 8)].try_into()?)); let mut next = orig; next += curr_carry; if next < orig { next_carry = Wrapping(1u64); } next += other_v; if next < other_v { next_carry = Wrapping(1u64); } wtr.extend_from_slice(&next.0.to_le_bytes()); curr_carry = next_carry; next_carry = Wrapping(0u64); ``` -------------------------------- ### Id Struct Construction and Utility Methods Source: https://docs.rs/negentropy/latest/src/negentropy/id.rs.html Provides methods for constructing `Id` instances from byte arrays and slices, along with methods to retrieve the inner byte array or a reference to it. Note the deprecation of `new` in favor of `from_byte_array`. ```rust impl Id { const LEN: usize = ID_SIZE; /// Construct from byte array #[deprecated(since = "1.0.0", note = "Use `from_byte_array` instead")] pub fn new(bytes: [u8; ID_SIZE]) -> Self { Self(bytes) } /// Construct event ID from 32-byte array #[inline] pub const fn from_byte_array(bytes: [u8; Self::LEN]) -> Self { Self(bytes) } /// Construct from slice #[inline] pub fn from_slice(slice: &[u8]) -> Result { // Check len if slice.len() != Self::LEN { return Err(Error::InvalidIdSize); } // Copy bytes let mut bytes: [u8; Self::LEN] = [0u8; Self::LEN]; bytes.copy_from_slice(slice); // Construct Ok(Self::from_byte_array(bytes)) } /// Return the inner value #[inline] pub fn to_bytes(self) -> [u8; Self::LEN] { self.0 } /// Return reference to the inner value #[inline] pub fn as_bytes(&self) -> &[u8; Self::LEN] { &self.0 } } ``` -------------------------------- ### CloneToUninit Trait Implementation (Nightly) Source: https://docs.rs/negentropy/latest/negentropy/struct.Item.html Implements the nightly-only experimental `CloneToUninit` trait. This trait allows for cloning data into uninitialized memory, which requires careful handling. ```rust impl CloneToUninit for T where T: Clone, ``` ```rust unsafe fn clone_to_uninit(&self, dest: *mut u8) ``` -------------------------------- ### Implement Ord for Bound Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Enables total ordering comparisons between Bound instances. Methods like `cmp()`, `max()`, `min()`, and `clamp()` are available. ```rust fn cmp(&self, other: &Self) -> Ordering ``` ```rust fn max(self, other: Self) -> Self where Self: Sized, ``` ```rust fn min(self, other: Self) -> Self where Self: Sized, ``` ```rust fn clamp(self, min: Self, max: Self) -> Self where Self: Sized, ``` -------------------------------- ### Item Trait Implementations Source: https://docs.rs/negentropy/latest/negentropy/struct.Item.html Details the trait implementations for the Item struct, such as Clone, Debug, Default, Hash, Ord, PartialEq, and PartialOrd. ```APIDOC ## Item Trait Implementations ### `impl Clone for Item` Allows creating duplicate instances of an Item. ### `impl Debug for Item` Enables formatting Item instances for debugging. ### `impl Default for Item` Provides a default value for Item instances. ### `impl Hash for Item` Allows Item instances to be hashed. ### `impl Ord for Item` Enables total ordering comparisons between Item instances. ### `impl PartialEq for Item` Allows equality comparisons between Item instances. ### `impl PartialOrd for Item` Enables partial ordering comparisons between Item instances. ### `impl Copy for Item` Indicates that Item instances can be copied implicitly. ### `impl Eq for Item` Marks Item as having a total equivalence relation. ### `impl StructuralPartialEq for Item` Enables structural equality comparisons. ``` -------------------------------- ### Define Protocol Version, ID Size, and Fingerprint Size Source: https://docs.rs/negentropy/latest/src/negentropy/constants.rs.html These constants define the protocol version, the size of identifiers, and the size of fingerprints used within the negentropy system. Ensure these values are consistent across all interacting components. ```rust 1// Copyright (c) 2023 Doug Hoyte 2// Copyright (c) 2023 Yuki Kishimoto 3// Distributed under the MIT software license 4 5/// Implemented protocol version 6pub const PROTOCOL_VERSION: u64 = 0x61; // Version 1 7 8/// ID Size 9pub const ID_SIZE: usize = 32; 10 11/// Fingerprint Size 12pub const FINGERPRINT_SIZE: usize = 16; ``` -------------------------------- ### NegentropyStorageVector Implementation Source: https://docs.rs/negentropy/latest/src/negentropy/storage.rs.html A concrete implementation of `NegentropyStorageBase` using a `Vec`, providing methods for insertion, sealing, and unsealing. ```APIDOC ## NegentropyStorageVector ### Description An implementation of `NegentropyStorageBase` that uses a `Vec` to store data. It supports insertion, sorting, deduplication, and sealing. ### Methods - **new**() -> Self - Creates a new, empty `NegentropyStorageVector`. - **with_capacity**(capacity: usize) -> Self - Creates a new `NegentropyStorageVector` with a specified initial capacity. - **insert**(&mut self, created_at: u64, id: Id) -> Result<(), Error> - Inserts a new item into the storage. Fails if the storage is sealed. - **seal**(&mut self) -> Result<(), Error> - Seals the storage, sorting and deduplicating items. Fails if already sealed. - **unseal**(&mut self) -> Result<(), Error> - Unseals the storage, allowing further modifications. ### Implemented Trait Methods (NegentropyStorageBase) - **size**(&self) -> Result - **get_item**(&self, i: usize) -> Result, Error> - **iterate**(&self, begin: usize, end: usize, cb: &mut dyn FnMut(Item, usize) -> Result) -> Result<(), Error> - **find_lower_bound**(&self, first: usize, last: usize, value: &Bound) -> usize ``` -------------------------------- ### Initiate Reconciliation Set Source: https://docs.rs/negentropy/latest/src/negentropy/lib.rs.html Initiates the reconciliation process by creating an initial message. This method should only be called once per instance. It returns the initial message payload. ```rust pub fn initiate(&mut self) -> Result, Error> { if self.is_initiator { return Err(Error::AlreadyBuiltInitialMessage); } self.is_initiator = true; let mut output: Vec = Vec::new(); output.push(PROTOCOL_VERSION as u8); output.extend(self.split_range(0, self.storage.size()?, Bound::with_timestamp(MAX_U64))?); Ok(output) } ``` -------------------------------- ### Implement Debug for Bound Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Enables formatted output for Bound instances, useful for debugging. The `fmt()` method is used internally by the Debug trait. ```rust fn fmt(&self, f: &mut Formatter<'_>) -> Result ``` -------------------------------- ### Implement StructuralPartialEq for Bound Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Enables structural equality checks for Bound instances, comparing fields for equality. ```rust impl StructuralPartialEq for Bound ``` -------------------------------- ### Calculate Fingerprint Source: https://docs.rs/negentropy/latest/negentropy/trait.NegentropyStorageBase.html The `fingerprint` method is a provided method that calculates a fingerprint for a range of items within the storage. This can be used for efficient comparison or integrity checks. ```rust fn fingerprint( &self, begin: usize, end: usize, ) -> Result { ... } ``` -------------------------------- ### Storage Trait Implementations Source: https://docs.rs/negentropy/latest/negentropy/enum.Storage.html Details the trait implementations for the Storage enum, including Debug, Deref, and others. ```APIDOC ## Trait Implementations for Storage<'a, T> ### Debug Allows the Storage enum to be formatted for debugging. ### Deref Enables dereferencing the Storage enum to access the underlying data. #### Target = T The type that the Storage enum dereferences to. #### fn deref(&self) -> &Self::Target Dereferences the value to access the inner data. ### Auto Trait Implementations - Freeze - RefUnwindSafe - Send - Sync - Unpin - UnwindSafe ### Blanket Implementations - Any - Borrow - BorrowMut - From - Into - Receiver - TryFrom - TryInto ``` -------------------------------- ### Reconcile with IDs (Client Method) Source: https://docs.rs/negentropy/latest/src/negentropy/lib.rs.html Processes a query from the server and returns a response, populating `have_ids` and `need_ids` vectors. This method is for the client-side. It returns `None` if reconciliation is complete. ```rust pub fn reconcile_with_ids( &mut self, query: &[u8], have_ids: &mut Vec, need_ids: &mut Vec, ) -> Result>, Error> { if !self.is_initiator { return Err(Error::NonInitiator); } let output: Vec = self.reconcile_aux(query, have_ids, need_ids)?; if output.len() == 1 { return Ok(None); } Ok(Some(output)) } ``` -------------------------------- ### Accumulator Operations Source: https://docs.rs/negentropy/latest/src/negentropy/types.rs.html This section details various operations on the Accumulator, such as negation, subtraction, and addition. ```APIDOC ## Accumulator Operations ### Negate Negates the current accumulator's buffer. ### Method `negate` ### Sub Item Subtracts an `Item`'s ID from the accumulator. ### Method `sub_item` ### Parameters #### Path Parameters - **item** (Item) - Required - The item to subtract. ### Sub Accum Subtracts another `Accumulator`'s buffer from the current accumulator. ### Method `sub_accum` ### Parameters #### Path Parameters - **accum** (Accumulator) - Required - The accumulator to subtract. ### Sub Subtracts a byte array from the accumulator. ### Method `sub` ### Parameters #### Path Parameters - **buf** ([u8; ID_SIZE]) - Required - The byte array to subtract. ### Add Accum Adds another `Accumulator`'s buffer to the current accumulator. ### Method `add_accum` ### Parameters #### Path Parameters - **accum** (Accumulator) - Required - The accumulator to add. ### Add Adds a byte array to the accumulator. ### Method `add` ### Parameters #### Path Parameters - **buf** ([u8; ID_SIZE]) - Required - The byte array to add. ``` -------------------------------- ### Create Negentropy Instance Source: https://docs.rs/negentropy/latest/negentropy/struct.Negentropy.html Constructs a new Negentropy instance using borrowed storage. The frame size limit must be 0 or greater than 4096. ```rust pub fn borrowed(storage: &'a T, frame_size_limit: u64) -> Result ``` -------------------------------- ### PROTOCOL_VERSION Constant Source: https://docs.rs/negentropy/latest/negentropy/constant.PROTOCOL_VERSION.html Represents the implemented protocol version. Use this constant to ensure compatibility with the negentropy protocol. ```rust pub const PROTOCOL_VERSION: u64 = 0x61; ``` -------------------------------- ### SHA-256 Benchmark Source: https://docs.rs/negentropy/latest/src/negentropy/sha256.rs.html A Rust benchmark function using the `test::Bencher` to measure the performance of the `hash` function with a constant input string. ```rust #[bench] pub fn sha256_hash(bh: &mut Bencher) { bh.iter(|| { black_box(hash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); }); } ``` -------------------------------- ### NegentropyStorageVector - Sealing and Borrowing Source: https://docs.rs/negentropy/latest/negentropy/struct.NegentropyStorageVector.html Information on sealing the storage and borrowing it for Negentropy operations. ```APIDOC ## NegentropyStorageVector - Sealing and Borrowing ### Description Operations related to finalizing the storage and preparing it for use with the Negentropy client. ### Methods #### `seal(&mut self) -> Result<(), Error>` Seals the storage, making it immutable and ready for use. This operation should be called after all items have been inserted. **Returns:** A `Result` indicating success or an `Error` if sealing fails. **Example:** ```rust let mut storage = NegentropyStorageVector::new(); // ... insert items ... storage.seal().unwrap(); ``` #### `borrowed(storage: &NegentropyStorageVector, version: u32) -> Result` Borrows the sealed storage to create a Negentropy client instance. This allows you to perform Negentropy operations using the stored data. **Parameters:** - **storage** (&NegentropyStorageVector) - A reference to the sealed `NegentropyStorageVector`. - **version** (u32) - The version of the Negentropy protocol to use. **Returns:** A `Result` containing a `Negentropy` client instance or an `Error`. **Example:** ```rust let mut storage = NegentropyStorageVector::new(); storage.seal().unwrap(); let mut client = Negentropy::borrowed(&storage, 0).unwrap(); ``` ``` -------------------------------- ### Initiate Reconciliation Set Source: https://docs.rs/negentropy/latest/negentropy/struct.Negentropy.html Initiates a reconciliation set. This method is part of the Negentropy reconciliation process. ```rust pub fn initiate(&mut self) -> Result, Error> ``` -------------------------------- ### Implement From for T Source: https://docs.rs/negentropy/latest/negentropy/struct.Bound.html Allows creating a value of type `T` from another value of the same type `T`. The `from()` method simply returns the input value. ```rust fn from(t: T) -> T ``` -------------------------------- ### NegentropyStorageVector - Creation Source: https://docs.rs/negentropy/latest/negentropy/struct.NegentropyStorageVector.html Provides methods for creating instances of NegentropyStorageVector. ```APIDOC ## NegentropyStorageVector - Creation ### Description Methods for creating and initializing a NegentropyStorageVector. ### Methods #### `new()` Creates a new, empty storage. **Example:** ```rust let mut storage = NegentropyStorageVector::new(); ``` #### `with_capacity(capacity: usize)` Creates a new storage with a specified initial capacity. **Parameters:** - **capacity** (usize) - The initial capacity for the storage. **Example:** ```rust let mut storage = NegentropyStorageVector::with_capacity(100); ``` ``` -------------------------------- ### NegentropyStorageVector Insert Method Source: https://docs.rs/negentropy/latest/src/negentropy/storage.rs.html Inserts a new item into the storage. This operation is only allowed if the storage is not sealed. It creates an `Item` from the provided timestamp and ID and appends it to the internal vector. ```rust /// Insert item pub fn insert(&mut self, created_at: u64, id: Id) -> Result<(), Error> { if self.sealed { return Err(Error::AlreadySealed); } let elem: Item = Item::with_timestamp_and_id(created_at, id); self.items.push(elem); Ok(()) } ``` -------------------------------- ### Check if Initiator Source: https://docs.rs/negentropy/latest/src/negentropy/lib.rs.html Returns `true` if the `Negentropy` instance has been used to create an initial message, indicating it's acting as the initiator. ```rust pub fn is_initiator(&self) -> bool { self.is_initiator } ```