Skip to main content

sim_codec_bridge/
part_book.rs

1use std::collections::BTreeMap;
2
3use sim_kernel::{Error, Expr, Result, Symbol};
4
5/// Rendering class for a registered BRIDGE part kind.
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub enum RenderClass {
8    /// Structural line in the packet face.
9    Structural,
10    /// Fluent frame sentence rendered from a typed frame.
11    Frame,
12    /// Non-instruction data rendered through a fence.
13    Data,
14    /// Evidence or attestation material.
15    Evidence,
16    /// Review text or structured review material.
17    Review,
18    /// Vote material.
19    Vote,
20    /// Patch material.
21    Patch,
22    /// Fetch request material.
23    Fetch,
24    /// Return contract material.
25    Return,
26    /// Receipt material.
27    Receipt,
28    /// Extension material.
29    Extension,
30}
31
32/// Authority class for a registered BRIDGE part kind.
33#[derive(Clone, Debug, PartialEq, Eq)]
34pub enum AuthorityClass {
35    /// Data only; it carries no instruction authority.
36    Data,
37    /// Normative instruction or obligation.
38    Normative,
39    /// Callable tool or model request material.
40    Callable,
41    /// Evidence, receipt, or review material.
42    Evidence,
43}
44
45/// Policy for preserving a part kind that is not in the standard normative book.
46#[derive(Clone, Debug, PartialEq, Eq)]
47pub enum UnknownPolicy {
48    /// Reject the part unless the kind is registered.
49    Reject,
50    /// Preserve the part as data only.
51    PreserveDataOnly,
52}
53
54/// Registered BRIDGE part-kind specification.
55#[derive(Clone, Debug, PartialEq, Eq)]
56pub struct BridgePartSpec {
57    /// Part kind symbol.
58    pub kind: Symbol,
59    /// Shape expression for the part payload.
60    pub shape_expr: Expr,
61    /// Rendering class.
62    pub render_class: RenderClass,
63    /// Authority class.
64    pub authority_class: AuthorityClass,
65    /// Unknown preservation policy.
66    pub unknown_policy: UnknownPolicy,
67}
68
69impl BridgePartSpec {
70    /// Builds a normative registered part spec.
71    pub fn new(
72        kind: Symbol,
73        shape_expr: Expr,
74        render_class: RenderClass,
75        authority_class: AuthorityClass,
76        unknown_policy: UnknownPolicy,
77    ) -> Self {
78        Self {
79            kind,
80            shape_expr,
81            render_class,
82            authority_class,
83            unknown_policy,
84        }
85    }
86
87    /// Builds a data-only preserving extension spec.
88    pub fn preserve_data_only(kind: Symbol, shape_expr: Expr) -> Self {
89        Self::new(
90            kind,
91            shape_expr,
92            RenderClass::Extension,
93            AuthorityClass::Data,
94            UnknownPolicy::PreserveDataOnly,
95        )
96    }
97}
98
99/// Registry of BRIDGE part-kind specifications.
100#[derive(Clone, Debug, Default, PartialEq, Eq)]
101pub struct BridgePartBook {
102    specs: BTreeMap<Symbol, BridgePartSpec>,
103}
104
105impl BridgePartBook {
106    /// Builds an empty part book.
107    pub fn new() -> Self {
108        Self::default()
109    }
110
111    /// Registers a part spec, replacing any existing spec for the same kind.
112    pub fn register(&mut self, spec: BridgePartSpec) {
113        self.specs.insert(spec.kind.clone(), spec);
114    }
115
116    /// Returns the registered spec for `kind`.
117    pub fn spec(&self, kind: &Symbol) -> Option<&BridgePartSpec> {
118        self.specs.get(kind)
119    }
120
121    /// Returns all registered part specs.
122    pub fn specs(&self) -> impl Iterator<Item = &BridgePartSpec> {
123        self.specs.values()
124    }
125
126    /// Checks that `kind` is registered for decoding.
127    pub fn require_registered(&self, kind: &Symbol) -> Result<&BridgePartSpec> {
128        self.spec(kind)
129            .ok_or_else(|| Error::Eval(format!("unknown BRIDGE part kind {kind}")))
130    }
131}
132
133/// A BRIDGE book bundles the part book and move book used for a packet.
134#[derive(Clone, Debug, PartialEq, Eq)]
135pub struct BridgeBook {
136    /// Registered part-kind specs.
137    pub parts: BridgePartBook,
138    /// Registered dialogue move specs.
139    pub moves: crate::BridgeMoveBook,
140    /// Registered fluent frame specs.
141    pub frames: crate::BridgeFrameBook,
142    /// Registered packet profile specs.
143    pub profiles: crate::BridgeProfileBook,
144    /// Policy for warrant verification by receivers using this book.
145    pub warrant_policy: crate::BridgeWarrantPolicy,
146}
147
148impl BridgeBook {
149    /// Builds a book from explicit part, move, frame, and profile books.
150    pub fn new(
151        parts: BridgePartBook,
152        moves: crate::BridgeMoveBook,
153        frames: crate::BridgeFrameBook,
154        profiles: crate::BridgeProfileBook,
155    ) -> Self {
156        Self {
157            parts,
158            moves,
159            frames,
160            profiles,
161            warrant_policy: crate::BridgeWarrantPolicy::SharedTrust,
162        }
163    }
164
165    /// Builds the standard BRIDGE book.
166    pub fn standard() -> Self {
167        Self::new(
168            crate::standard_part_book(),
169            crate::standard_move_book(),
170            crate::standard_frame_book(),
171            crate::standard_profile_book(),
172        )
173    }
174
175    /// Returns a copy with one more part spec registered.
176    pub fn with_part(mut self, spec: BridgePartSpec) -> Self {
177        self.parts.register(spec);
178        self
179    }
180
181    /// Returns a copy with one more frame spec registered.
182    pub fn with_frame(mut self, spec: crate::FrameSpec) -> Self {
183        self.frames.register(spec);
184        self
185    }
186
187    /// Returns a copy with one more profile spec registered.
188    pub fn with_profile(mut self, spec: crate::BridgeProfileSpec) -> Self {
189        self.profiles.register(spec);
190        self
191    }
192
193    /// Returns a copy with the warrant verification policy set.
194    pub fn with_warrant_policy(mut self, policy: crate::BridgeWarrantPolicy) -> Self {
195        self.warrant_policy = policy;
196        self
197    }
198}
199
200/// Builds the standard BRIDGE part book.
201pub fn standard_part_book() -> BridgePartBook {
202    let mut book = BridgePartBook::new();
203    for spec in [
204        spec("Given", RenderClass::Data, AuthorityClass::Data),
205        spec("Frame", RenderClass::Frame, AuthorityClass::Normative),
206        spec("Call", RenderClass::Structural, AuthorityClass::Callable),
207        spec("Weave", RenderClass::Structural, AuthorityClass::Normative),
208        spec("Check", RenderClass::Structural, AuthorityClass::Normative),
209        spec("Evidence", RenderClass::Evidence, AuthorityClass::Evidence),
210        spec("Review", RenderClass::Review, AuthorityClass::Evidence),
211        spec("Vote", RenderClass::Vote, AuthorityClass::Evidence),
212        spec("Patch", RenderClass::Patch, AuthorityClass::Normative),
213        spec("Fetch", RenderClass::Fetch, AuthorityClass::Callable),
214        spec("Return", RenderClass::Return, AuthorityClass::Normative),
215        spec("Receipt", RenderClass::Receipt, AuthorityClass::Evidence),
216        spec("Attest", RenderClass::Evidence, AuthorityClass::Evidence),
217        spec("Extension", RenderClass::Extension, AuthorityClass::Data),
218    ] {
219        book.register(spec);
220    }
221    book
222}
223
224fn spec(name: &str, render_class: RenderClass, authority_class: AuthorityClass) -> BridgePartSpec {
225    let kind = Symbol::qualified("bridge", name);
226    BridgePartSpec::new(
227        kind.clone(),
228        Expr::Symbol(kind),
229        render_class,
230        authority_class,
231        UnknownPolicy::Reject,
232    )
233}