Skip to main content

macroonz_compiler/codec/
bank.rs

1//! The codec home's authored bill and reserved decode bindings.
2//!
3//! The public bill and both generated roads read one rendering row, so a wire shape cannot move one without moving all three.
4
5use super::spell::{
6    CANDIDATE_BINDING, CARRIED_BINDING, CHOSEN_BINDING, COLLECTED_BINDING, ELECTED_BINDING,
7    INTO_BINDING, LENGTH_BINDING, MATERIAL_BINDING, NESTED_BINDING, PRESENT_BINDING,
8    REMAINING_BINDING, WIDTH_BINDING,
9};
10use super::types::{ReadRoad, RenderingContract, WriteRoad};
11use super::{
12    CodecMemberShape, DECODE_ROAD, ENCODE_ROAD, MemberContract, ROSTER_CONSTANT, SLOT_ROAD,
13};
14
15/// The complete bill, one row per wire shape, in the roster's own order.
16///
17/// Five rows because the roster is five: a row added here without an arm beside it, or an arm without a row, is a length disagreement the declaration itself carries.
18///
19/// The closed-choice row is this compiler's own contract on a caller's roster — a complete roster constant and a position road answering one byte — and not an inheritance from any stamp that happens to emit one.
20pub const MEMBER_CONTRACT: [MemberContract; 5] = [
21    COUNT_CONTRACT.bill,
22    BYTES_CONTRACT.bill,
23    TEXT_CONTRACT.bill,
24    CLOSED_CHOICE_CONTRACT.bill,
25    NESTED_CONTRACT.bill,
26];
27
28const COUNT_CONTRACT: RenderingContract = RenderingContract {
29    bill: MemberContract {
30        shape: CodecMemberShape::Count,
31        encode_road: "u64::from",
32        decode_road: "<T as ::core::convert::TryFrom<u64>>::try_from",
33    },
34    write: WriteRoad::Count,
35    read: ReadRoad::Count,
36};
37
38const BYTES_CONTRACT: RenderingContract = RenderingContract {
39    bill: MemberContract {
40        shape: CodecMemberShape::Bytes,
41        encode_road: "<T as ::core::convert::AsRef<[u8]>>::as_ref",
42        decode_road: "<T as ::core::convert::TryFrom<::std::vec::Vec<u8>>>::try_from",
43    },
44    write: WriteRoad::Bytes,
45    read: ReadRoad::Bytes,
46};
47
48const TEXT_CONTRACT: RenderingContract = RenderingContract {
49    bill: MemberContract {
50        shape: CodecMemberShape::Text,
51        encode_road: "<T as ::core::convert::AsRef<str>>::as_ref",
52        decode_road: "<T as ::core::convert::TryFrom<::std::string::String>>::try_from",
53    },
54    write: WriteRoad::Text,
55    read: ReadRoad::Text,
56};
57
58const CLOSED_CHOICE_CONTRACT: RenderingContract = RenderingContract {
59    bill: MemberContract {
60        shape: CodecMemberShape::ClosedChoice,
61        encode_road: SLOT_ROAD,
62        decode_road: ROSTER_CONSTANT,
63    },
64    write: WriteRoad::ClosedChoice,
65    read: ReadRoad::ClosedChoice,
66};
67
68const NESTED_CONTRACT: RenderingContract = RenderingContract {
69    bill: MemberContract {
70        shape: CodecMemberShape::Nested,
71        encode_road: ENCODE_ROAD,
72        decode_road: DECODE_ROAD,
73    },
74    write: WriteRoad::Nested,
75    read: ReadRoad::Nested,
76};
77
78/// The authoritative row one member shape selects.
79///
80/// Both the public bill and generated operations read this seat, so adding or reassigning a shape cannot leave an independently selected renderer behind it.
81pub(super) const fn rendering_contract(shape: CodecMemberShape) -> RenderingContract {
82    match shape {
83        CodecMemberShape::Count => COUNT_CONTRACT,
84        CodecMemberShape::Bytes => BYTES_CONTRACT,
85        CodecMemberShape::Text => TEXT_CONTRACT,
86        CodecMemberShape::ClosedChoice => CLOSED_CHOICE_CONTRACT,
87        CodecMemberShape::Nested => NESTED_CONTRACT,
88    }
89}
90
91/// The locals the rendered decode road declares for itself.
92///
93/// # Authority
94///
95/// **A member whose spelling is one of these is refused rather than renamed.**
96/// The decode road binds one local per member under the member's OWN spelling, which is what makes the rendered road readable and what lets the assembly call name its arguments the way the owner named its members.
97/// A member colliding with one of these would shadow the rendering's own binding, and the road would go on reading a value nobody meant — a defect that compiles.
98///
99/// Renaming the rendering's locals to something nobody would write is not the repair: an unreadable rendered road is a road nobody can audit, and the collision would still exist for whatever names were chosen instead.
100pub const RESERVED_BINDINGS: [&str; 12] = [
101    MATERIAL_BINDING,
102    REMAINING_BINDING,
103    INTO_BINDING,
104    NESTED_BINDING,
105    COLLECTED_BINDING,
106    CANDIDATE_BINDING,
107    CHOSEN_BINDING,
108    ELECTED_BINDING,
109    PRESENT_BINDING,
110    CARRIED_BINDING,
111    LENGTH_BINDING,
112    WIDTH_BINDING,
113];