Skip to content

(9) feat: fixed-size + lookup foundation trait crates#1573

Open
daniel-noland wants to merge 2 commits into
pr/daniel-noland/dpdk-test-ealfrom
pr/daniel-noland/fixed-size-lookup
Open

(9) feat: fixed-size + lookup foundation trait crates#1573
daniel-noland wants to merge 2 commits into
pr/daniel-noland/dpdk-test-ealfrom
pr/daniel-noland/fixed-size-lookup

Conversation

@daniel-noland
Copy link
Copy Markdown
Collaborator

@daniel-noland daniel-noland commented May 31, 2026

Stack (9). Base: pr/daniel-noland/dpdk-test-eal.

The two foundational leaf trait crates the match-action / ACL layers build on.
No DPDK, no unsafe:

  • feat(fixed-size): FixedSize trait crate + impls for net wire newtypes.
  • feat(lookup): Lookup<K, A> + Projection<T> trait crate.

Review stack (merge bottom -> top):

Introduces a no_std FixedSize trait carrying a known byte width plus
a big-endian write.  Lives in its own crate so value-providing
crates (`net`) and downstream key-packing frameworks (a future
`match-action` PR) can both depend on it without depending on each
other -- `net` implements FixedSize on its own newtypes without an
orphan-rule violation, and the framework doesn't need to know about
any particular value supplier.

fixed-size/src/lib.rs:

- pub trait FixedSize: Copy, with const SIZE: usize and fn
  write_be(&self, out: &mut [u8]).
- Blanket impls for the network-order primitives the framework cares
  about: u8 / u16 / u32 / u64 / u128 / Ipv4Addr / Ipv6Addr.

net/src/fixed_size.rs is the consumer bridge: FixedSize impls for
TcpPort, UdpPort, UnicastIpv4Addr, and Vni.  Each delegates write_be
to the underlying primitive's impl, so wire bytes match what writing
the raw integer would produce.  Vni is a 24-bit value written into a
4-byte field (high byte zero) because backends model fields in 1/2/4
widths, not 3.

net/Cargo.toml grows the fixed-size workspace dep; net/src/lib.rs
adds the module behind no cfg gates (it has no further dependencies
of its own).

just fmt; cargo check --workspace --all-targets passes.
Adds the read-only key/action lookup vocabulary downstream match-action
backends will implement.  Tiny crate by design (one trait pair, two
collection impls, inline tests) so consumer crates depend on this
without depending on each other.

lookup/src/lib.rs:

- pub trait Projection<T>: extracts a key of type T from self.
  Implemented on `&'a Source` so the lifetime threads into T when T
  borrows; for owned T the lifetime is unused.  The same source can
  implement Projection<T> for many T -- the call site picks one by
  inference from a Lookup backend's key type.
- impl<K> Projection<Option<K>> for Option<K>: identity, so
  classify_opt accepts a pre-computed Option<K> directly.  Scoped to
  Option<K> (not a general impl<T> Projection<T> for T) so a backend
  that implements Lookup<K, A> for every K can't make classify
  ambiguous.
- pub trait Lookup<K, A>: lookup(&K) -> Option<&A>, plus default
  methods classify (S: Projection<K>) and classify_opt (S:
  Projection<Option<K>>) that project and look up in one call.  Two
  trait type parameters, so one backend can serve many (K, A) pairs.
- Blanket Lookup impls for BTreeMap<K, V> and HashMap<K, V, S> so
  tests / simple consumers get a working backend out of the box.

Inline tests exercise: projection-by-table-type inference at v4
2-tuple and 4-tuple widths, lifetime threading through borrowed
projections, miss returning None, classify_opt short-circuit on None
projection, the identity Projection<Option<K>> for Option<K>, and
HashMap parity with BTreeMap.

just fmt; cargo check --workspace --all-targets passes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces two new foundational trait crates (fixed-size and lookup) intended to underpin upcoming match-action / ACL layers, and wires FixedSize implementations for selected net wire newtypes.

Changes:

  • Added dataplane-fixed-size (no_std) defining a FixedSize trait plus base impls for integer and IP address types.
  • Added dataplane-lookup defining Lookup<K, A> and Projection<T> traits with BTreeMap/HashMap backends and unit tests.
  • Integrated fixed-size into net and provided FixedSize impls for TcpPort, UdpPort, UnicastIpv4Addr, and Vni.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
net/src/lib.rs Registers a private fixed_size module to host FixedSize impls for net types.
net/src/fixed_size.rs Implements FixedSize for key net newtypes and adds unit tests for byte encoding.
net/Cargo.toml Adds dependency on the new fixed-size crate.
fixed-size/src/lib.rs Adds the new FixedSize trait crate and core impls for primitives/IP types.
fixed-size/Cargo.toml Declares the new dataplane-fixed-size crate.
lookup/src/lib.rs Adds the new Lookup/Projection trait crate plus unit tests and map backends.
lookup/Cargo.toml Declares the new dataplane-lookup crate.
Cargo.toml Adds both crates to the workspace, workspace dependencies, and wasm/miri metadata.
Cargo.lock Records the two new workspace packages and updates dataplane-net deps.

Comment thread fixed-size/src/lib.rs
Comment on lines +15 to +18
pub trait FixedSize: Copy {
const SIZE: usize;
fn write_be(&self, out: &mut [u8]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants