Skip to main content

macroonz_compiler/render/
types.rs

1//! The render home's declarations: the ceiling one rendered unit's bytes stand under, one materialized unit, the whole rendering, the sink a renderer writes into, and how rendering says no.
2//!
3//! Declarations only.
4//! Every road that reaches a private field lives in `type_guard.rs`, this file's own child, which is what makes the digest structural: it is taken there over the tree's own canonical bytes, and no caller supplies one.
5
6use crate::bounded::NonEmpty;
7use crate::identity::{self, Identity, OwnerIdentity, Profile};
8use crate::kind::{Kind, Role};
9use crate::origin::OriginTrail;
10use crate::plan::{MEMBERSHIP_LIMIT, Plan};
11use crate::token::GeneratedTree;
12
13#[path = "type_guard.rs"]
14mod guard;
15
16/// Bytes one rendered unit may carry.
17///
18/// A renderer that would emit past this refuses rather than materializing part of a unit.
19pub const RENDERED_BYTE_LIMIT: usize = 65_536;
20
21/// One unit a renderer actually materialized.
22///
23/// Its seat and every fact that seat's planned member states are carried, so a proof can rebuild a membership out of a rendering and compare it against the declared one; the tree, the identity, and the digest are the rendering's own.
24///
25/// # Nonclaims
26///
27/// The Rust source text is not a member of the unit.
28/// It is [`GeneratedTree::inspected`](crate::token::GeneratedTree::inspected) — a projection of the tree, for a person.
29#[derive(Debug, Clone, PartialEq, Eq)]
30pub struct RenderedUnit<R: Role> {
31    role: R,
32    identity: Identity<identity::RenderedUnit>,
33    semantic_key: Identity<identity::GeneratedUnit>,
34    profile: Profile,
35    origin: OriginTrail,
36    address: Option<OwnerIdentity>,
37    tree: GeneratedTree,
38    digest: Identity<identity::OutputBytes>,
39}
40
41/// Everything one renderer produced for one plan.
42///
43/// Structurally non-empty: a rendering that materialized nothing is not a rendering, and no plan can ever close over one.
44/// Bounded by the magnitude a plan declares its membership inside, because a rendering wider than any plan could declare has no plan to close over.
45#[derive(Debug, Clone, PartialEq, Eq)]
46pub struct RenderedProjection<R: Role> {
47    units: NonEmpty<RenderedUnit<R>, MEMBERSHIP_LIMIT>,
48}
49
50/// The value a renderer writes its units into.
51///
52/// It holds the plan, so a renderer names a seat and hands over tokens: everything else one unit carries is that seat's planned member, read here.
53/// It holds no proof and makes none — a seat left unfilled and a seat filled twice are written into it as freely as an honest rendering, because those are disagreements between a rendering and a plan and the proof that compares the two is what settles them.
54pub struct Output<'plan, K: Kind> {
55    plan: &'plan Plan<K>,
56    units: Vec<RenderedUnit<K::Role>>,
57}
58
59/// How rendering says no.
60///
61/// One refusal, at the first thing that goes wrong: a unit that cannot be materialized is not a unit, and the units after it were never written.
62/// Three rows name a declared magnitude and the two counts that passed it; the other two say a rendering and a plan's seats do not line up at all.
63#[must_use = "a rendering refusal names the seat or the magnitude the renderer would have passed"]
64#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
65pub enum RenderError {
66    /// The renderer wrote no unit at all.
67    NothingRendered,
68    /// A unit was written under a seat this plan declares no member for.
69    ///
70    /// Refused where it is written rather than where a proof would notice it, because a unit answers to its member's semantic key and a seat with no member offers none.
71    SeatUnplanned {
72        /// The seat's declared name.
73        role: &'static str,
74    },
75    /// One unit's canonical bytes pass the declared magnitude.
76    BytesUnbounded {
77        /// The seat the unit was written under, by its declared name.
78        role: &'static str,
79        /// The declared bound.
80        bound: usize,
81        /// The observed count.
82        observed: usize,
83    },
84    /// The rendering carries more units than the declared magnitude admits.
85    UnitsUnbounded {
86        /// The declared bound.
87        bound: usize,
88        /// The observed count.
89        observed: usize,
90    },
91    /// A generated tree passed the declared per-level magnitude while a unit was being composed.
92    ///
93    /// The one overflow a renderer meets: the composition helpers and the tree assembler are what it builds with, and they are the only roads it takes that bound anything.
94    TokensUnbounded {
95        /// The declared bound.
96        bound: usize,
97        /// The observed count.
98        observed: usize,
99    },
100}