Skip to main content

Region

Struct Region 

Source
pub struct Region<T: Flat, B: Buf = AlignedBuf<T>> { /* private fields */ }
Expand description

An owning, contiguous byte buffer whose root value T starts at byte 0.

All Near and NearList pointers inside the region are self-relative offsets, so Clone is a plain memcpy — no fixup needed.

§Memory layout

┌──────────────────────────────────────────────┐
│ Root T (starts at byte 0)                    │
│  ├── scalar fields (inline)                  │
│  ├── Near<U> → i32 offset ───────┐           │
│  └── NearList<V> → i32 + u32 ──┐ │           │
│                                │ │           │
│ [padding]                      │ │           │
│ U value ◄──────────────────────│─┘           │
│ [padding]                      │             │
│ Segment<V> header ◄────────────┘             │
│ V values...                                  │
└──────────────────────────────────────────────┘

§Soundness

Ownership: A Region exclusively owns its buffer. There is no shared mutable state. Clone performs a byte-for-byte copy of the buffer; all self-relative offsets remain valid because they are position-independent.

Alignment: The buffer base is aligned to max(align_of::<T>(), 8). Every sub-allocation is padded to the target type’s alignment. A compile-time assertion ensures no type exceeds the buffer’s base alignment.

Mutation safety: All mutations go through Session, which holds &mut Region. The branded 'id lifetime on Ref prevents refs from escaping or crossing sessions.

Send/Sync: Implemented with T: Send + Sync bounds as defense-in-depth. All Flat types are Send + Sync by construction (no heap pointers, no interior mutability), but the bounds let the compiler verify this.

Implementations§

Source§

impl<T: Flat> Region<T>

Source

pub fn new(builder: impl Emit<T>) -> Self

Construct a region from a builder using the default AlignedBuf.

The builder emits the root T (and any nested data) into a fresh emitter, producing an immutable Region.

§Examples
use nearest::{Flat, NearList, Region, empty, list};

#[derive(Flat, Debug)]
struct Node {
  id: u32,
  children: NearList<u32>,
}

// Build with the derive-generated `Node::make(id, children)` builder.
let region = Region::new(Node::make(1, list([10u32, 20, 30])));
assert_eq!(region.id, 1);
assert_eq!(region.children.len(), 3);

// Build with an empty list.
let region = Region::new(Node::make(2, empty()));
assert_eq!(region.children.len(), 0);
Source

pub fn with_capacity(capacity: u32, builder: impl Emit<T>) -> Self

Construct a region with a pre-allocated buffer of at least capacity bytes.

Avoids repeated reallocations when the final size is approximately known.

Source§

impl<T: Flat, B: Buf> Region<T, B>

Source

pub fn new_in(builder: impl Emit<T>) -> Self

Construct a region from a builder using an explicit buffer type B.

For the default heap-backed buffer, use Region::new instead.

Source

pub fn with_capacity_in(capacity: u32, builder: impl Emit<T>) -> Self

Construct a region with a pre-allocated buffer of at least capacity bytes.

Source

pub fn session<R>( &mut self, f: impl for<'id> FnOnce(&mut Session<'id, '_, T, B>) -> R, ) -> R

Open a branded session. Refs created inside the closure cannot escape or be used with a different session — compile-time safety, zero runtime cost.

§Examples
use nearest::{Flat, NearList, Region, empty, list};

#[derive(Flat, Debug)]
struct Node {
  id: u32,
  children: NearList<u32>,
}

let mut region = Region::new(Node::make(1, list([10u32, 20])));

// Read and mutate inside a session.
region.session(|s| {
  let root = s.root();
  assert_eq!(s.at(root).id, 1);

  let children = s.nav(root, |n| &n.children);
  s.splice_list(children, [99u32]);
});

assert_eq!(region.children.len(), 1);
assert_eq!(region.children[0], 99);
Source

pub fn byte_len(&self) -> usize

Returns the total byte length of the region.

§Examples
use nearest::{Flat, NearList, Region, empty};

#[derive(Flat)]
struct Node { id: u32, items: NearList<u32> }

let region = Region::new(Node::make(1, empty()));
assert!(region.byte_len() >= core::mem::size_of::<Node>());
Source

pub fn trim(&mut self)

Compact this region by re-emitting only reachable data.

After mutations (e.g. splice_list, push_front), old targets of redirected Near/NearList pointers become dead bytes. trim walks the root T and all transitively reachable data, emitting a fresh compact buffer via Emit<T> for &T deep-copy.

§Examples
use nearest::{Flat, NearList, Region, list};

#[derive(Flat, Debug)]
struct Node { items: NearList<u32> }

let mut region = Region::new(Node::make(list([1u32, 2, 3])));
let before = region.byte_len();

// Mutation leaves dead bytes (old list data).
region.session(|s| {
  let items = s.nav(s.root(), |n| &n.items);
  s.splice_list(items, [42u32]);
});
assert!(region.byte_len() > before);

// Trim compacts the region.
region.trim();
assert!(region.byte_len() <= before);
assert_eq!(region.items[0], 42);
Source

pub fn as_bytes(&self) -> &[u8]

Return the raw byte contents of this region.

The returned slice can be persisted (e.g. written to a file) and later restored via from_bytes.

§Examples
use nearest::{Flat, NearList, Region, empty, list};

#[derive(Flat, Debug)]
struct Node {
  id: u32,
  children: NearList<u32>,
}

let region = Region::new(Node::make(1, list([10u32, 20, 30])));
let bytes = region.as_bytes();
assert!(bytes.len() >= core::mem::size_of::<Node>());
Source

pub fn into_buf(self) -> B

Consume the region and return the underlying buffer.

This is a zero-copy operation — it simply unwraps the inner buffer. The returned buffer can be passed to from_bytes (via Buf::as_bytes) for reconstruction, or converted to bytes.

§Examples
use nearest::{Flat, NearList, Region, empty, list};

#[derive(Flat, Debug)]
struct Node {
  id: u32,
  children: NearList<u32>,
}

let region = Region::new(Node::make(1, list([10u32, 20, 30])));
let buf = region.into_buf();
Source

pub fn into_vec(self) -> Vec<u8>

Consume the region and return its contents as a Vec<u8>.

The returned vector contains the same bytes as as_bytes. This is useful for APIs that need an owned byte buffer (e.g. I/O, network transmission, or storage). The bytes can later be restored via Region::from_bytes.

§Examples
use nearest::{Flat, NearList, Region, list};

#[derive(Flat, Debug)]
struct Node {
  id: u32,
  children: NearList<u32>,
}

let region = Region::new(Node::make(1, list([10u32, 20, 30])));
let bytes: Vec<u8> = region.into_vec();
let restored: Region<Node> = Region::from_bytes(&bytes).unwrap();
assert_eq!(restored.id, 1);
assert_eq!(restored.children.len(), 3);
Source

pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidateError>

Validate and reconstruct a region from raw bytes.

Copies the bytes into an aligned buffer first, then runs T::validate on the copy. This copy-then-validate order means the input is read only once (during the copy), and validation reads the cache-hot aligned buffer instead.

§Errors

Returns ValidateError if the bytes do not form a valid representation of T and its transitively reachable data.

§Examples

Round-trip through bytes:

use nearest::{Flat, NearList, Region, empty, list};

#[derive(Flat, Debug)]
struct Node {
  id: u32,
  children: NearList<u32>,
}

let original = Region::new(Node::make(1, list([10u32, 20, 30])));
let bytes = original.as_bytes();
let restored: Region<Node> = Region::from_bytes(bytes).unwrap();
assert_eq!(restored.id, 1);
assert_eq!(restored.children.len(), 3);

Validation catches invalid data — here a bool field with value 2:

use nearest::{Flat, Near, Region, ValidateError, near};

#[derive(Flat, Debug)]
struct Flags {
  active: bool,
  label: Near<u32>,
}

let region = Region::new(Flags::make(true, near(42u32)));
let mut bytes = region.as_bytes().to_vec();
// Corrupt the bool — its offset is computed from the struct layout.
let bool_offset = core::mem::offset_of!(Flags, active);
bytes[bool_offset] = 2;
assert!(matches!(
  Region::<Flags>::from_bytes(&bytes),
  Err(ValidateError::InvalidBool { .. })
));
Source

pub unsafe fn from_bytes_unchecked(bytes: &[u8]) -> Self

Reconstruct a region from raw bytes without validation.

This is the unsafe fast path for deserialization. The bytes are copied into a fresh aligned buffer but no validation is performed — no bounds checks, no pointer validation, no discriminant checks.

For a safe alternative that validates the buffer, use from_bytes.

§Safety

The caller must guarantee all of the following:

  • bytes was originally produced by as_bytes on a valid Region<T> (or is byte-for-byte identical to such output).
  • The buffer contains a valid representation of T at byte offset 0, with correct size (bytes.len() >= size_of::<T>()).
  • All Near<U> self-relative offsets resolve to in-bounds, correctly aligned addresses within the buffer, and the target bytes form a valid U.
  • All NearList<U> headers have in-bounds segment chains with correct lengths, and every element is a valid U.
  • All enum discriminants are valid for their #[repr].
  • All bool values are 0 or 1.
  • No Option<Near<T>> contains a bit pattern that is neither None nor a valid Some(Near<T>).

Violating any of these preconditions causes undefined behavior on subsequent reads through the region.

§Examples
use nearest::{Flat, NearList, Region, list};

#[derive(Flat, Debug)]
struct Node {
  id: u32,
  children: NearList<u32>,
}

let original = Region::new(Node::make(1, list([10u32, 20, 30])));
let bytes = original.as_bytes();

// SAFETY: `bytes` was produced by `as_bytes()` on a valid `Region<Node>`.
let restored: Region<Node> = unsafe { Region::from_bytes_unchecked(bytes) };
assert_eq!(restored.id, 1);
assert_eq!(restored.children.len(), 3);
Source

pub unsafe fn from_buf_unchecked(buf: B) -> Self

Reconstruct a region from a pre-existing buffer without validation.

Unlike from_bytes_unchecked, this takes an already-allocated buffer B, avoiding an extra copy when the caller already has an aligned buffer (e.g. memory-mapped I/O with a FixedBuf).

§Safety

The caller must guarantee all of the following:

  • buf contains a valid representation of T at byte offset 0, with buf.len() >= size_of::<T>().
  • The buffer base is aligned to at least align_of::<T>() (guaranteed by the Buf trait, but the contents must also be valid).
  • All Near<U> self-relative offsets resolve to in-bounds, correctly aligned addresses within the buffer, and the target bytes form a valid U.
  • All NearList<U> headers have in-bounds segment chains with correct lengths, and every element is a valid U.
  • All enum discriminants are valid for their #[repr].
  • All bool values are 0 or 1.
  • No Option<Near<T>> contains a bit pattern that is neither None nor a valid Some(Near<T>).

Violating any of these preconditions causes undefined behavior on subsequent reads through the region.

§Examples
use nearest::{Buf, Flat, NearList, Region, FixedBuf, list};

#[derive(Flat, Debug)]
struct Node {
  id: u32,
  children: NearList<u32>,
}

let original: Region<Node, FixedBuf<256>> =
  Region::new_in(Node::make(1, list([10u32, 20, 30])));
let bytes = original.as_bytes();

let mut buf = FixedBuf::<256>::new();
buf.extend_from_slice(bytes);

// SAFETY: `buf` contains bytes from a valid `Region<Node>`.
let restored: Region<Node, FixedBuf<256>> =
  unsafe { Region::from_buf_unchecked(buf) };
assert_eq!(restored.id, 1);
assert_eq!(restored.children.len(), 3);

Trait Implementations§

Source§

impl<T: Flat, B: Buf> AsRef<[u8]> for Region<T, B>

Source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<T: Flat, B: Buf + Clone> Clone for Region<T, B>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Flat + Debug, B: Buf> Debug for Region<T, B>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Flat, B: Buf> Deref for Region<T, B>

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &T

Dereferences the value.
Source§

impl<'de, T: Flat, B: Buf> Deserialize<'de> for Region<T, B>

Available on crate feature serde only.
Source§

fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<T: Flat + Display, B: Buf> Display for Region<T, B>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Flat, B: Buf> From<Region<T, B>> for Vec<u8>

Available on crate feature alloc only.
Source§

fn from(region: Region<T, B>) -> Self

Converts to this type from the input type.
Source§

impl<T: Flat + PartialEq, B: Buf> PartialEq for Region<T, B>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: Flat, B: Buf> Serialize for Region<T, B>

Available on crate feature serde only.
Source§

fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>

Serialize this value into the given Serde serializer. Read more
Source§

impl<T: Flat + Eq, B: Buf> Eq for Region<T, B>

Source§

impl<T: Flat + Send + Sync, B: Buf + Send> Send for Region<T, B>

Source§

impl<T: Flat + Send + Sync, B: Buf + Sync> Sync for Region<T, B>

Auto Trait Implementations§

§

impl<T, B> Freeze for Region<T, B>
where B: Freeze,

§

impl<T, B> RefUnwindSafe for Region<T, B>

§

impl<T, B> Unpin for Region<T, B>
where B: Unpin, T: Unpin,

§

impl<T, B> UnsafeUnpin for Region<T, B>
where B: UnsafeUnpin,

§

impl<T, B> UnwindSafe for Region<T, B>
where B: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,