Skip to main content

static_bindings_catalog/
static_bindings_catalog.rs

1//! v0.2.2 Phase Q.3 example: build a compile-time `BindingsTable` from static
2//! `Binding` declarations using Phase P.3's `to_binding_entry` helper.
3//!
4//! Downstream declares a `'static [Binding]` array (as produced by the
5//! `uor!` macro or manual compile-time construction), then lifts each
6//! `Binding` to a `BindingEntry` via `to_binding_entry()`. The result is a
7//! `'static [BindingEntry]` array consumable by `BindingsTable::try_new`.
8//!
9//! The admission is entirely compile-time:
10//! - `ContentAddress::from_u64_fingerprint` is const-fn
11//! - `Binding::to_binding_entry` is const-fn
12//! - `BindingsTable::try_new` is const-fn (validates sort order)
13//!
14//! Run with: `cargo run --example static_bindings_catalog -p uor-foundation`
15
16use uor_foundation::enforcement::{Binding, BindingEntry, BindingsTable};
17
18static BINDINGS: &[Binding] = &[
19    Binding {
20        name_index: 0,
21        type_index: 0,
22        value_index: 0,
23        surface: "x",
24        content_address: 0x0000_0000_0000_0001,
25    },
26    Binding {
27        name_index: 1,
28        type_index: 0,
29        value_index: 1,
30        surface: "y",
31        content_address: 0x0000_0000_0000_00ff,
32    },
33    Binding {
34        name_index: 2,
35        type_index: 0,
36        value_index: 2,
37        surface: "z",
38        content_address: 0x0000_0000_0000_ffff,
39    },
40];
41
42// Lift each Binding to a BindingEntry at const-time. `to_binding_entry` maps
43// `content_address: u64` → `ContentAddress::from_u64_fingerprint` (left-shifted
44// into high bits) and re-uses `surface.as_bytes()` as `&'static [u8]`.
45static ENTRIES: &[BindingEntry] = &[
46    BINDINGS[0].to_binding_entry(),
47    BINDINGS[1].to_binding_entry(),
48    BINDINGS[2].to_binding_entry(),
49];
50
51// Validate sort order at const-time. try_new checks strict-ascending ContentAddress.
52const TABLE: BindingsTable = match BindingsTable::try_new(ENTRIES) {
53    Ok(t) => t,
54    Err(_) => panic!("bindings are not in strict-ascending ContentAddress order"),
55};
56
57fn main() {
58    println!("Static BindingsTable with {} entries:", TABLE.entries.len());
59    for entry in TABLE.entries {
60        println!(
61            "  address={:?} bytes={:?}",
62            entry.address,
63            core::str::from_utf8(entry.bytes).expect("surface is utf8")
64        );
65    }
66
67    // Lookup: binary search by address (BindingsTable entries are sorted).
68    let lookup_addr = BINDINGS[1].to_binding_entry().address;
69    let found = TABLE
70        .entries
71        .binary_search_by_key(&lookup_addr.as_u128(), |e| e.address.as_u128())
72        .map(|idx| &TABLE.entries[idx]);
73
74    match found {
75        Ok(entry) => println!(
76            "Lookup found: {:?}",
77            core::str::from_utf8(entry.bytes).unwrap_or("?")
78        ),
79        Err(_) => println!("Lookup miss"),
80    }
81}