### Queue Module Usage Example - Rust Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/index_search= Demonstrates how to initialize flash memory, define a flash range, and use the queue's push, peek, and pop functions to manage data. It shows asynchronous operations and assertions for verifying data integrity. This example assumes `init_flash()` and `NoCache::new()` are defined elsewhere and that the necessary traits are in scope. ```rust use sequential_storage::queue::{pop, peek, push}; use std::ops::Range; // Mock implementations for demonstration purposes struct MockFlash; impl MockFlash { async fn write(&mut self, _range: Range, _data: &[u8]) -> Result<(), ()> { Ok(()) } async fn read(&mut self, _range: Range) -> Result, ()> { Ok(vec![]) } async fn erase(&mut self, _range: Range) -> Result<(), ()> { Ok(()) } } struct NoCache; impl NoCache { fn new() -> Self { NoCache } } async fn init_flash() -> MockFlash { MockFlash } #[tokio::main] async fn main() { // Initialize the flash. This can be internal or external let mut flash = init_flash().await; // These are the flash addresses in which the crate will operate. // The crate will not read, write or erase outside of this range. let flash_range = 0x1000..0x3000; // We need to give the crate a buffer to work with. // It must be big enough to serialize the biggest value of your storage type in. let mut data_buffer = [0; 128]; let my_data = [10, 47, 29]; // We can push some data to the queue push(&mut flash, flash_range.clone(), &mut NoCache::new(), &my_data, false).await.unwrap(); // We can peek at the oldest data assert_eq!( &peek(&mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer).await.unwrap().unwrap()[..], &my_data[..] ); // With popping we get back the oldest data, but that data is now also removed assert_eq!( &pop(&mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer).await.unwrap().unwrap()[..], &my_data[..] ); // If we pop again, we find there's no data anymore assert_eq!( pop(&mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer).await, Ok(None) ); } ``` -------------------------------- ### Example Usage of fetch_all_items Iterator - Rust Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/map/fn.fetch_all_items_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates how to use the 'fetch_all_items' function to get an iterator and populate a HashMap with the key-value pairs. It highlights the need to handle potential duplicate keys, as the last returned item for a given key is considered the active one. The example assumes Key and Value types are u8 and u32 respectively. ```rust let mut flash = init_flash(); let flash_range = 0x1000..0x3000; let mut data_buffer = [0; 128]; let mut cache = NoCache::new(); // Create the iterator of map items let mut iterator = fetch_all_items::( &mut flash, flash_range.clone(), &mut cache, &mut data_buffer ) .await .unwrap(); let mut all_items = HashMap::new(); // Iterate through all items, suppose the Key and Value types are u8, u32 while let Some((key, value)) = iterator .next::(&mut data_buffer) .await .unwrap() { // Do somethinmg with the item. // Please note that for the same key there might be multiple items returned, // the last one is the current active one. all_items.insert(key, value); } ``` -------------------------------- ### Slice Prefix Check Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search= Determines if a slice starts with a given prefix slice or is identical to it. ```APIDOC ## GET /slice/starts_with ### Description Returns `true` if the slice starts with the `needle` slice or is equal to it. ### Method GET ### Endpoint `/slice/starts_with` ### Parameters #### Query Parameters - **needle** (array of T) - Required - The slice to check as a prefix. ### Request Example ```json { "slice": [10, 40, 30], "needle": [10, 40] } ``` ### Response #### Success Response (200) - **result** (boolean) - `true` if the `needle` is a prefix or the slice itself, `false` otherwise. #### Response Example ```json { "result": true } ``` ``` -------------------------------- ### Implement QueueIteratorEntry Methods Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search= Provides implementations for QueueIteratorEntry, including methods to get a mutable reference to the entry's data and to pop the data from flash. ```rust impl<'d, S: NorFlash, CI: CacheImpl> QueueIteratorEntry<'_, 'd, '_, S, CI> { pub fn into_buf(self) -> &'d mut [u8] pub async fn pop(self) -> Result<&'d mut [u8], Error> } ``` -------------------------------- ### split_at Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search=u32+-%3E+bool Divides one slice into two at a given index. The first part contains elements from the start up to (but not including) the index, and the second part contains elements from the index to the end. ```APIDOC ## split_at ### Description Divides one slice into two at an index. The first will contain all indices from `[0, mid)` and the second will contain all indices from `[mid, len)`. ### Method `split_at` ### Endpoint `/split_at/{mid}` ### Parameters #### Path Parameters - **mid** (usize) - Required - The index at which to split the slice. #### Query Parameters None #### Request Body None ### Request Example ```rust let v = ['a', 'b', 'c']; let (left, right) = v.split_at(2); ``` ### Response #### Success Response (200) - **(&[T], &[T])** - A tuple containing two slices: the left part and the right part. #### Response Example ```rust // For v = ['a', 'b', 'c'] and mid = 2 // ('a', 'b') and ('c') ``` ### Panics Panics if `mid > len`. ``` -------------------------------- ### Serialization and Deserialization for String Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/map/trait.Key_search=u32+-%3E+bool Provides methods to serialize and deserialize String to and from a byte buffer, and to get its length. ```APIDOC ## `impl Key for String` ### Description This implementation provides serialization and deserialization capabilities for a generic `String` type with a specified capacity. ### Methods #### `serialize_into(&self, buffer: &mut [u8]) -> Result` Serializes the `String` into the provided mutable byte buffer. #### `deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError>` Deserializes a `String` from the provided byte buffer. #### `get_len(buffer: &[u8]) -> Result` Retrieves the length of the serialized `String` from the buffer without deserializing the entire content. ``` -------------------------------- ### Initialize, Store, and Fetch Items in Sequential Storage (Rust) Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/map/index_search=std%3A%3Avec Demonstrates the basic API for initializing flash memory, storing a key-value pair, and fetching it back. It highlights the need for consistent key and value types and provides example usage with `u8` keys and `u32` values. Dependencies include an `init_flash` function and a `NoCache` implementation. ```rust use sequential_storage::{init_flash, NoCache, fetch_item, store_item}; // Initialize the flash. This can be internal or external // let mut flash = init_flash(); // These are the flash addresses in which the crate will operate. // The crate will not read, write or erase outside of this range. // let flash_range = 0x1000..0x3000; // We need to give the crate a buffer to work with. // It must be big enough to serialize the biggest value of your storage type in, // // rounded up to to word alignment of the flash. Some kinds of internal flash may require // // this buffer to be aligned in RAM as well. // let mut data_buffer = [0; 128]; // // We can fetch an item from the flash. We're using `u8` as our key type and `u32` as our value type. // // Nothing is stored in it yet, so it will return None. // // // assert_eq!( // // fetch_item::( // // &mut flash, // // flash_range.clone(), // // &mut NoCache::new(), // // &mut data_buffer, // // &42, // // ).await.unwrap(), // // None // // ); // // // Now we store an item the flash with key 42. // // Again we make sure we pass the correct key and value types, u8 and u32. // // It is important to do this consistently. // // store_item( // &mut flash, // flash_range.clone(), // &mut NoCache::new(), // &mut data_buffer, // &42u8, // &104729u32, // ).await.unwrap(); // // // When we ask for key 42, we now get back a Some with the correct value // // assert_eq!( // fetch_item::( // &mut flash, // flash_range.clone(), // &mut NoCache::new(), // &mut data_buffer, // &42, // ).await.unwrap(), // Some(104729) // ); ``` -------------------------------- ### GET /websites/rs_sequential-storage_6_0_1_sequential_storage/rchunks Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search=std%3A%3Avec Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end of the slice. ```APIDOC ## GET /websites/rs_sequential-storage_6_0_1_sequential_storage/rchunks ### Description Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end of the slice. The chunks are slices and do not overlap. ### Method GET ### Endpoint `/websites/rs_sequential-storage_6_0_1_sequential_storage/rchunks` ### Parameters #### Path Parameters None #### Query Parameters - **slice** (&[T]) - Required - The slice to get chunks from. - **chunk_size** (usize) - Required - The desired size of each chunk. ### Request Example ```json { "slice": [0, 0, 0, 0, 0], "chunk_size": 2 } ``` ### Response #### Success Response (200) - **iterator** (RChunks<'_, T>) - An iterator yielding slices of the specified chunk size from the end. #### Response Example ```json { "iterator": [ [1, 1], [2, 2], [9] ] } ``` ### Panics Panics if `chunk_size` is zero. ``` -------------------------------- ### Implement and Use a Flash Memory Queue in Rust Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/index_search=std%3A%3Avec Demonstrates the initialization and usage of the sequential-storage queue in Rust. It shows how to set up flash memory, push data, peek at the oldest data, and pop data from the queue. This example requires flash initialization and a data buffer. ```Rust use sequential_storage::queue::push; use sequential_storage::queue::peek; use sequential_storage::queue::pop; use sequential_storage::cache::NoCache; // Assume init_flash() is defined elsewhere and returns a flash memory handler // fn init_flash() -> impl FlashStorage { // // ... implementation ... // } #[tokio::main] async fn main() { // Initialize the flash. This can be internal or external let mut flash = init_flash(); // These are the flash addresses in which the crate will operate. // The crate will not read, write or erase outside of this range. let flash_range = 0x1000..0x3000; // We need to give the crate a buffer to work with. // It must be big enough to serialize the biggest value of your storage type in. let mut data_buffer = [0; 128]; let my_data = [10, 47, 29]; // We can push some data to the queue push(&mut flash, flash_range.clone(), &mut NoCache::new(), &my_data, false).await.unwrap(); // We can peek at the oldest data assert_eq!( &peek(&mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer).await.unwrap().unwrap()[..], &my_data[..] ); // With popping we get back the oldest data, but that data is now also removed assert_eq!( &pop(&mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer).await.unwrap().unwrap()[..], &my_data[..] ); // If we pop again, we find there's no data anymore assert_eq!( pop(&mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer).await, Ok(None) ); } ``` -------------------------------- ### GET /websites/rs_sequential-storage_6_0_1_sequential_storage/array_windows Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search=std%3A%3Avec Returns an iterator over overlapping windows of `N` elements of a slice, starting at the beginning. This is a nightly-only experimental API. ```APIDOC ## GET /websites/rs_sequential-storage_6_0_1_sequential_storage/array_windows ### Description Returns an iterator over overlapping windows of `N` elements of a slice, starting at the beginning of the slice. This is the const generic equivalent of `windows`. ### Method GET ### Endpoint `/websites/rs_sequential-storage_6_0_1_sequential_storage/array_windows` ### Parameters #### Path Parameters - **N** (const generic) - Required - The size of each window. #### Query Parameters - **slice** (&[T]) - Required - The slice to get windows from. ### Request Example ```json { "slice": [0, 1, 2, 3], "N": 2 } ``` ### Response #### Success Response (200) - **iterator** (ArrayWindows<'_, T, N>) - An iterator yielding `N`-element array slices. #### Response Example ```json { "iterator": [ [0, 1], [1, 2], [2, 3] ] } ``` ### Panics Panics if `N` is zero. ``` -------------------------------- ### GET /api/slice/rchunks Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end of the slice. ```APIDOC ## GET /api/slice/rchunks ### Description Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end of the slice. The chunks are slices and do not overlap. ### Method GET ### Endpoint `/api/slice/rchunks` ### Parameters #### Query Parameters - **chunk_size** (usize) - Required - The size of each chunk. - **slice** (&[T]) - Required - The slice to chunk. ### Request Example `GET /api/slice/rchunks?chunk_size=2&slice=[1, 2, 3, 4, 5]` ### Response #### Success Response (200) - **chunks** (Iterator) - An iterator yielding slices of `chunk_size` elements from the end. #### Response Example (Note: This is a conceptual representation as iterators are not directly serializable) * First call to `next()`: `[4, 5]` * Second call to `next()`: `[2, 3]` * Third call to `next()`: `[1]` * Fourth call to `next()`: `None` ### Panics Panics if `chunk_size` is zero. ``` -------------------------------- ### Basic API Operations Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/map/index_search= Demonstrates the fundamental operations of the sequential-storage crate, including initialization, storing, and fetching key-value pairs from flash memory. ```APIDOC ## Basic API Operations ### Description This section details the basic usage of the sequential-storage crate for initializing flash memory, storing key-value pairs, and retrieving stored values. ### Key Concepts - **Flash Initialization**: Setting up the flash memory interface. - **Flash Range**: Defining the memory region the crate will operate within. - **Data Buffer**: A buffer required for serialization/deserialization of values. - **Key-Value Storage**: Storing and fetching data associated with unique keys. ### Core Functions Demonstrated: - `init_flash()`: Initializes the flash memory (example placeholder). - `fetch_item()`: Retrieves a value associated with a given key. - `store_item()`: Stores a key-value pair into flash memory. ### Example Usage: ```rust // Initialize the flash. This can be internal or external let mut flash = init_flash(); // These are the flash addresses in which the crate will operate. // The crate will not read, write or erase outside of this range. let flash_range = 0x1000..0x3000; // We need to give the crate a buffer to work with. // It must be big enough to serialize the biggest value of your storage type in, // rounded up to to word alignment of the flash. Some kinds of internal flash may require // this buffer to be aligned in RAM as well. let mut data_buffer = [0; 128]; // Fetch an item (initially None as nothing is stored) assert_eq!( fetch_item::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), None ); // Store an item store_item( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42u8, &104729u32, ).await.unwrap(); // Fetch the stored item assert_eq!( fetch_item::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), Some(104729) ); ``` ### Important Considerations: - **Key Type Consistency**: It is crucial to use the same key type for all operations within a given flash range to ensure data integrity. - **Value Type Flexibility**: While the key type must be consistent, different value types can be used for different keys, provided serialization and deserialization are handled correctly. - **`fetch_all_items` Requirement**: This function also requires all items to have the same value type. ``` -------------------------------- ### Basic API for Sequential Storage in Rust Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/map/index_search=u32+-%3E+bool Demonstrates the fundamental operations of initializing flash memory, defining a storage range, and using a data buffer. It shows how to store a key-value pair (u8 key, u32 value) and then fetch it back, including handling cases where the item is not yet stored. This API is crucial for interacting with the sequential-storage crate. ```rust async fn run_example() { // Initialize the flash. This can be internal or external let mut flash = init_flash(); // These are the flash addresses in which the crate will operate. // The crate will not read, write or erase outside of this range. let flash_range = 0x1000..0x3000; // We need to give the crate a buffer to work with. // It must be big enough to serialize the biggest value of your storage type in, // rounded up to to word alignment of the flash. Some kinds of internal flash may require // this buffer to be aligned in RAM as well. let mut data_buffer = [0; 128]; // We can fetch an item from the flash. We're using `u8` as our key type and `u32` as our value type. // Nothing is stored in it yet, so it will return None. assert_eq!( fetch_item::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), None ); // Now we store an item the flash with key 42. // Again we make sure we pass the correct key and value types, u8 and u32. // It is important to do this consistently. store_item( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42u8, &104729u32, ).await.unwrap(); // When we ask for key 42, we now get back a Some with the correct value assert_eq!( fetch_item::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), Some(104729) ); } ``` -------------------------------- ### Rust: Get Element Offset for Unaligned Element (Nightly) Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search= Demonstrates a scenario where `element_offset` returns `None` because the element reference is not aligned with the start of a slice element. This occurs when a reference points to memory between elements, highlighting the method's reliance on pointer alignment. ```rust #![feature(substr_range)] let arr: &[[u32; 2]] = &[[0, 1], [2, 3]]; let flat_arr: &[u32] = arr.as_flattened(); let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap(); let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap(); assert_eq!(ok_elm, &[0, 1]); assert_eq!(weird_elm, &[1, 2]); assert_eq!(arr.element_offset(ok_elm), Some(0)); // Points to element 0 assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1 ``` -------------------------------- ### Rust: Get Disjoint Unchecked Mutable Slice Elements Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search= Provides examples of using `get_disjoint_unchecked_mut` to obtain mutable references to multiple disjoint elements or sub-slices within a mutable slice without bounds checking. This method is unsafe and requires careful handling to avoid undefined behavior due to overlapping or out-of-bounds indices. ```rust let x = &mut [1, 2, 4]; unsafe { let [a, b] = x.get_disjoint_unchecked_mut([0, 2]); *a *= 10; *b *= 100; } assert_eq!(x, &[10, 2, 400]); ``` ```rust let x = &mut [1, 2, 4]; unsafe { let [a, b] = x.get_disjoint_unchecked_mut([0..1, 1..3]); a[0] = 8; b[0] = 88; b[1] = 888; } assert_eq!(x, &[8, 88, 888]); ``` ```rust let x = &mut [1, 2, 4]; unsafe { let [a, b] = x.get_disjoint_unchecked_mut([1..=2, 0..=0]); a[0] = 11; a[1] = 111; b[0] = 1; } assert_eq!(x, &[1, 11, 111]); ``` -------------------------------- ### Basic API for Flash Storage and Retrieval Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/map/index_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates the fundamental operations of the sequential-storage crate: initializing flash memory, defining a flash range, preparing a data buffer, storing a key-value pair, and fetching a value by its key. It highlights the use of generic types for keys and values and the NoCache mechanism. This example assumes an asynchronous environment for flash operations. ```rust use sequential_storage::no_cache::NoCache; use sequential_storage::{fetch_item, store_item}; // Assume init_flash() is defined elsewhere and returns an async Flash trait object. // async fn init_flash() -> impl Flash; #[tokio::main] async fn main() { // Initialize the flash. This can be internal or external let mut flash = init_flash().await; // These are the flash addresses in which the crate will operate. // The crate will not read, write or erase outside of this range. let flash_range = 0x1000..0x3000; // We need to give the crate a buffer to work with. // It must be big enough to serialize the biggest value of your storage type in, // rounded up to to word alignment of the flash. Some kinds of internal flash may require // this buffer to be aligned in RAM as well. let mut data_buffer = [0; 128]; // We can fetch an item from the flash. We're using `u8` as our key type and `u32` as our value type. // Nothing is stored in it yet, so it will return None. assert_eq!( fetch_item::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), None ); // Now we store an item the flash with key 42. // Again we make sure we pass the correct key and value types, u8 and u32. // It is important to do this consistently. store_item( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42u8, &104729u32, ).await.unwrap(); // When we ask for key 42, we now get back a Some with the correct value assert_eq!( fetch_item::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), Some(104729) ); } // Placeholder for the actual flash initialization function. // In a real scenario, this would be provided by the hardware abstraction layer. async fn init_flash() -> impl sequential_storage::FlashAccess> { // Mock implementation for demonstration purposes struct MockFlash { /* internal state */ } impl sequential_storage::FlashAccess for MockFlash { async fn read(&mut self, _address: u32, _data: &mut [u8]) -> Result<(), sequential_storage::FlashError> { Ok(()) } async fn write(&mut self, _address: u32, _data: &[u8]) -> Result<(), sequential_storage::FlashError> { Ok(()) } async fn erase(&mut self, _range: std::ops::Range) -> Result<(), sequential_storage::FlashError> { Ok(()) } fn size(&self) -> u32 { 0x10000 } // Example size fn page_size(&self) -> u32 { 128 } // Example page size } MockFlash { /* initialize state */ } } ``` -------------------------------- ### Rust: Get Element Offset in Slice (Nightly) Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search= Illustrates the usage of the `element_offset` method, an experimental nightly-only API, to find the index of an element reference within a slice. It returns `Some(index)` if the element reference points to the start of an element, and `None` otherwise. This method relies on pointer arithmetic and does not compare element values. It panics if `T` is zero-sized. ```rust #![feature(substr_range)] let nums: &[u32] = &[1, 7, 1, 1]; let num = &nums[2]; assert_eq!(num, &1); assert_eq!(nums.element_offset(num), Some(2)); ``` -------------------------------- ### Sequential Storage API Overview Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/all_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E This section provides an overview of the available data structures and functions within the sequential-storage crate. ```APIDOC ## Sequential Storage API This crate provides functionalities for sequential data storage with features like caching, mapping, and queuing. ### Structs * `cache::KeyPointerCache`: A cache implementation using key pointers. * `cache::NoCache`: A cache implementation that does not cache anything. * `cache::PagePointerCache`: A cache implementation using page pointers. * `cache::PageStateCache`: A cache implementation for page states. * `map::MapItemIter`: An iterator for items in a map. * `queue::QueueIterator`: An iterator for a queue. * `queue::QueueIteratorEntry`: An entry within the queue iterator. ### Enums * `Error`: Represents potential errors in the storage operations. * `map::SerializationError`: Represents errors during map serialization. ### Traits * `cache::CacheImpl`: Trait for cache implementations. * `cache::KeyCacheImpl`: Trait for key-based cache implementations. * `map::Key`: Trait for keys used in the map. * `map::Value`: Trait for values stored in the map. ### Functions * `erase_all()`: Erases all data from the storage. * `item_overhead_size()`: Calculates the overhead size of an item. * `map::fetch_all_items()`: Fetches all items from the map. * `map::fetch_item(key)`: Fetches a specific item from the map by its key. * `map::remove_all_items()`: Removes all items from the map. * `map::remove_item(key)`: Removes a specific item from the map by its key. * `map::store_item(key, value)`: Stores an item in the map. * `queue::find_max_fit(size)`: Finds the maximum fit for a given size in the queue. * `queue::iter()`: Returns an iterator for the queue. * `queue::peek()`: Peeks at the front element of the queue without removing it. * `queue::pop()`: Removes and returns the front element of the queue. * `queue::push(item)`: Pushes an item onto the queue. * `queue::space_left()`: Returns the remaining space in the queue. ``` -------------------------------- ### Get Mutable Element or Subslice by Index (Rust) Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search= Returns a mutable reference to an element or subslice based on the provided index type. If the index is out of bounds, it returns `None`. Similar to `get`, but allows for in-place modification of the slice content. ```rust pub fn get_mut( &mut self, index: I, ) -> Option<&mut >::Output> where I: SliceIndex<[T]> { // ... implementation details ... } // Example Usage: let x = &mut [0, 1, 2]; if let Some(elem) = x.get_mut(1) { *elem = 42; } assert_eq!(x, &[0, 42, 2]); ``` -------------------------------- ### Basic API Usage for Storing and Fetching Items in Flash Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/map/index_search= Demonstrates the basic API for initializing flash memory, defining a flash range, and using a data buffer. It shows how to store a key-value pair (u8 key, u32 value) and then fetch it back, verifying the stored data. This example assumes an asynchronous context for flash operations. ```rust async fn example() { // Initialize the flash. This can be internal or external let mut flash = init_flash(); // These are the flash addresses in which the crate will operate. // The crate will not read, write or erase outside of this range. let flash_range = 0x1000..0x3000; // We need to give the crate a buffer to work with. // It must be big enough to serialize the biggest value of your storage type in, // rounded up to to word alignment of the flash. Some kinds of internal flash may require // this buffer to be aligned in RAM as well. let mut data_buffer = [0; 128]; // We can fetch an item from the flash. We're using `u8` as our key type and `u32` as our value type. // Nothing is stored in it yet, so it will return None. assert_eq!( fetch_item::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), None ); // Now we store an item the flash with key 42. // Again we make sure we pass the correct key and value types, u8 and u32. // It is important to do this consistently. store_item( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42u8, &104729u32, ).await.unwrap(); // When we ask for key 42, we now get back a Some with the correct value assert_eq!( fetch_item::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), Some(104729) ); } ``` -------------------------------- ### Key Trait Implementations Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/map/trait.Key This section details the implementations of the Key trait for different sequential storage types, including methods for serialization, deserialization, and getting the length of the serialized data. ```APIDOC ## Key Trait Implementations This document outlines the implementations of the `Key` trait for various sequential data structures. The `Key` trait provides methods for serializing data into a byte buffer, deserializing data from a byte buffer, and determining the length of the serialized data. ### `Vec` #### Methods - `serialize_into(&self, buffer: &mut [u8]) -> Result`: Serializes the `Vec` into the provided buffer. - `deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError>`: Deserializes a `Vec` from the provided buffer. - `get_len(buffer: &[u8]) -> Result`: Gets the length of the serialized `Vec` from the buffer. ### `String` #### Methods - `serialize_into(&self, buffer: &mut [u8]) -> Result`: Serializes the `String` into the provided buffer. - `deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError>`: Deserializes a `String` from the provided buffer. - `get_len(buffer: &[u8]) -> Result`: Gets the length of the serialized `String` from the buffer. ### `Vec` #### Methods - `serialize_into(&self, buffer: &mut [u8]) -> Result`: Serializes the `Vec` into the provided buffer. - `deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError>`: Deserializes a `Vec` from the provided buffer. - `get_len(buffer: &[u8]) -> Result`: Gets the length of the serialized `Vec` from the buffer. ### `ArrayString` #### Methods - `serialize_into(&self, buffer: &mut [u8]) -> Result`: Serializes the `ArrayString` into the provided buffer. - `deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError>`: Deserializes an `ArrayString` from the provided buffer. - `get_len(_buffer: &[u8]) -> Result`: Gets the length of the serialized `ArrayString` from the buffer. ### `ArrayVec` #### Methods - `serialize_into(&self, buffer: &mut [u8]) -> Result`: Serializes the `ArrayVec` into the provided buffer. - `deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError>`: Deserializes an `ArrayVec` from the provided buffer. - `get_len(buffer: &[u8]) -> Result`: Gets the length of the serialized `ArrayVec` from the buffer. ### `String` #### Methods - `serialize_into(&self, buffer: &mut [u8]) -> Result`: Serializes the `String` into the provided buffer. - `deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError>`: Deserializes a `String` from the provided buffer. - `get_len(buffer: &[u8]) -> Result`: Gets the length of the serialized `String` from the buffer. ### `Vec` #### Methods - `serialize_into(&self, buffer: &mut [u8]) -> Result`: Serializes the `Vec` into the provided buffer. - `deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError>`: Deserializes a `Vec` from the provided buffer. - `get_len(buffer: &[u8]) -> Result`: Gets the length of the serialized `Vec` from the buffer. ### `[u8; N]` #### Methods - `serialize_into(&self, buffer: &mut [u8]) -> Result`: Serializes the `[u8; N]` array into the provided buffer. - `deserialize_from(buffer: &[u8]) -> Result<(Self, usize), SerializationError>`: Deserializes a `[u8; N]` array from the provided buffer. - `get_len(_buffer: &[u8]) -> Result`: Gets the length of the serialized `[u8; N]` array from the buffer. ``` -------------------------------- ### Get Mutable Element or Subslice by Index (Rust) Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/struct.QueueIteratorEntry_search=std%3A%3Avec Returns a mutable reference to an element or subslice based on the provided index type. Similar to `get` but allows modification. Returns `None` if the index is out of bounds. ```rust let x = &mut [0, 1, 2]; if let Some(elem) = x.get_mut(1) { *elem = 42; } assert_eq!(x, &[0, 42, 2]); ``` -------------------------------- ### PagePointerCache Constructor Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/cache/struct.PagePointerCache_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Constructs a new instance of PagePointerCache. ```APIDOC ## Constructor: PagePointerCache::new ### Description Constructs a new instance of `PagePointerCache`. ### Method `const fn new() -> Self` ### Parameters None ### Returns A new instance of `PagePointerCache`. ``` -------------------------------- ### Basic API for Flash Storage and Retrieval in Rust Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/map/index Demonstrates the fundamental usage of the sequential-storage crate for storing and fetching key-value pairs from flash memory. It covers initialization, defining the flash range, preparing a data buffer, storing an item, and then retrieving it. This example assumes the use of `u8` for keys and `u32` for values and utilizes a `NoCache` implementation for flash access. ```rust use sequential_storage::Storage; use std::ops::Range; // Mock implementations for demonstration purposes struct MockFlash; impl MockFlash { async fn write(&mut self, _address: usize, _data: &[u8]) -> Result<(), ()> { Ok(()) } async fn read(&mut self, _address: usize, _buffer: &mut [u8]) -> Result { Ok(0) } async fn erase(&mut self, _range: Range) -> Result<(), ()> { Ok(()) } } struct NoCache; impl NoCache { fn new() -> Self { NoCache } } // Placeholder for actual crate functions, assuming they exist and are imported async fn init_flash() -> MockFlash { MockFlash } async fn fetch_item(_ flash: &mut MockFlash, _flash_range: Range, _cache: &mut C, _data_buffer: &mut [u8], _key: &K, ) -> Result, sequential_storage::SerializationError> where K: sequential_storage::Key + serde::Serialize + serde::de::DeserializeOwned, V: serde::Serialize + serde::de::DeserializeOwned, C: sequential_storage::Cache, { // Mock implementation detail Ok(None) } async fn store_item( _flash: &mut MockFlash, _flash_range: Range, _cache: &mut C, _data_buffer: &mut [u8], _key: &K, _value: &V, ) -> Result<(), sequential_storage::SerializationError> where K: sequential_storage::Key + serde::Serialize + serde::de::DeserializeOwned, V: serde::Serialize + serde::de::DeserializeOwned, C: sequential_storage::Cache, { // Mock implementation detail Ok(()) } #[tokio::main] async fn main() { // Initialize the flash. This can be internal or external let mut flash = init_flash().await; // These are the flash addresses in which the crate will operate. // The crate will not read, write or erase outside of this range. let flash_range = 0x1000..0x3000; // We need to give the crate a buffer to work with. // It must be big enough to serialize the biggest value of your storage type in, // rounded up to to word alignment of the flash. Some kinds of internal flash may require // this buffer to be aligned in RAM as well. let mut data_buffer = [0; 128]; // We can fetch an item from the flash. We're using `u8` as our key type and `u32` as our value type. // Nothing is stored in it yet, so it will return None. assert_eq!( fetch_item::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), None ); // Now we store an item the flash with key 42. // Again we make sure we pass the correct key and value types, u8 and u32. // It is important to do this consistently. store_item( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42u8, &104729u32, ).await.unwrap(); // When we ask for key 42, we now get back a Some with the correct value // Mocking the fetch_item to return Some(104729) for demonstration // In a real scenario, this would depend on the actual flash content. async fn fetch_item_mock(_ flash: &mut MockFlash, _flash_range: Range, _cache: &mut C, _data_buffer: &mut [u8], key: &K, ) -> Result, sequential_storage::SerializationError> where K: sequential_storage::Key + serde::Serialize + serde::de::DeserializeOwned, V: serde::Serialize + serde::de::DeserializeOwned, C: sequential_storage::Cache, { if key.eq(&42) { // Assuming Key trait has an eq method or similar for comparison Ok(Some(unsafe { std::mem::transmute::(104729) })) // Unsafe cast for mock } else { Ok(None) } } assert_eq!( fetch_item_mock::( &mut flash, flash_range.clone(), &mut NoCache::new(), &mut data_buffer, &42, ).await.unwrap(), Some(104729) ); } ``` -------------------------------- ### GET /queue/iter Source: https://docs.rs/sequential-storage/6.0.1/sequential_storage/queue/fn.iter Get an iterator-like interface to iterate over the items stored in the queue. This goes from oldest to newest. The iteration happens non-destructively, or in other words it peeks at every item. The returned entry has a QueueIteratorEntry::pop function with which you can decide to pop the item after you’ve seen the contents. ```APIDOC ## GET /queue/iter ### Description Provides a non-destructive iterator to traverse queue items from oldest to newest. Allows peeking at items and optionally popping them after inspection. ### Method GET ### Endpoint /queue/iter ### Parameters #### Query Parameters - **flash** (object reference) - Required - A mutable reference to the flash storage implementation. - **flash_range** (Range) - Required - The range within the flash storage to consider for the queue. - **cache** (object reference) - Required - A mutable reference to the cache implementation. ### Request Body None ### Response #### Success Response (200) - **QueueIterator** (object) - An iterator object that allows peeking at queue items and optionally popping them. - **entry** (object) - Represents an item in the queue during iteration. - **pop** (function) - A function to pop the current item after inspection. #### Response Example ```json { "iterator": "QueueIteratorObject" } ``` ```