diff --git a/CHANGELOG.md b/CHANGELOG.md index 46ab1a5..a2ec948 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## Unreleased +- added example demonstrating `ByteArea` with multiple typed sections, concurrent mutations, and freezing or persisting the area - added example combining Python bindings with winnow parsing - added Python example demonstrating structured parsing with winnow's `view` - added `ByteSource` support for `VecDeque` when `zerocopy` is enabled and kept the deque as owner diff --git a/README.md b/README.md index 16492d7..8e93477 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,10 @@ The area only aligns allocations to the element type and may share pages between adjacent sections to minimize wasted space. Multiple sections may be active simultaneously; their byte ranges do not overlap. +See [`examples/byte_area.rs`](examples/byte_area.rs) for a complete example +that reserves different typed sections, mutates them simultaneously, and then +either freezes the area into `Bytes` or persists it to disk. + ## Features By default the crate enables the `mmap` and `zerocopy` features. @@ -149,6 +153,7 @@ needs these libraries installed; otherwise disable the feature during testing. - [`examples/from_python.rs`](examples/from_python.rs) – wrap a Python `bytes` object into `Bytes` - [`examples/python_winnow.rs`](examples/python_winnow.rs) – parse Python bytes with winnow - [`examples/python_winnow_view.rs`](examples/python_winnow_view.rs) – parse structured data from Python bytes using winnow's `view` +- [`examples/byte_area.rs`](examples/byte_area.rs) – reserve and mutate multiple typed sections, then either freeze the area into `Bytes` or persist it to disk ## Comparison diff --git a/examples/byte_area.rs b/examples/byte_area.rs new file mode 100644 index 0000000..7c1a44a --- /dev/null +++ b/examples/byte_area.rs @@ -0,0 +1,39 @@ +use anybytes::{area::ByteArea, Bytes}; +use tempfile::tempdir; + +fn main() -> std::io::Result<()> { + let mut area = ByteArea::new()?; + let mut sections = area.sections(); + + // Reserve two sections at once and mutate them independently. + let mut raw = sections.reserve::(4)?; + let mut nums = sections.reserve::(2)?; + + raw.as_mut_slice().copy_from_slice(b"test"); + nums.as_mut_slice().copy_from_slice(&[1, 2]); + + // Freeze the sections into immutable `Bytes`. + let frozen_raw: Bytes = raw.freeze()?; + let frozen_nums: Bytes = nums.freeze()?; + assert_eq!(frozen_raw.as_ref(), b"test"); + assert_eq!(frozen_nums.view::<[u32]>().unwrap().as_ref(), &[1, 2]); + + drop(sections); + + // Decide whether to keep the area in memory or persist it to disk. + let memory_or_file = true; + if memory_or_file { + // Freeze the whole area into immutable `Bytes`. + let all: Bytes = area.freeze()?; + assert_eq!(&all[..4], b"test"); + assert_eq!(all.slice(4..).view::<[u32]>().unwrap().as_ref(), &[1, 2]); + } else { + // Persist the temporary file. + let dir = tempdir()?; + let path = dir.path().join("area.bin"); + area.persist(&path)?; + assert!(path.exists()); + } + + Ok(()) +}