Skip to main content

macroonz_compiler/diagnostic/
type_contract.rs

1//! The constant tables this home's rosters settle, and the one posture a span table's answer takes.
2//!
3//! Nothing here computes and nothing here decides; the deciding happened where the table was asked.
4//! Each table is total, so a row admitted later stops the compiler until somebody says what that row's stable name and sentence are.
5
6use super::{
7    DiagnosticNameRefusal, Observed, Phase, RefusalClass, RenderedMagnitude, SiteCoordinate,
8};
9use crate::token::{SourceCoordinate, SpanResolutionRefusal};
10
11impl Phase {
12    /// Every step of the road, in the order the steps run.
13    pub const ALL: &'static [Self] = &[
14        Self::Capture,
15        Self::Planning,
16        Self::Rendering,
17        Self::Closure,
18        Self::Explanation,
19        Self::Binding,
20        Self::Assembly,
21    ];
22
23    /// The step's stable name.
24    #[must_use]
25    pub const fn name(self) -> &'static str {
26        match self {
27            Self::Capture => "capture",
28            Self::Planning => "planning",
29            Self::Rendering => "rendering",
30            Self::Closure => "closure",
31            Self::Explanation => "explanation",
32            Self::Binding => "binding",
33            Self::Assembly => "assembly",
34        }
35    }
36}
37
38impl RefusalClass {
39    /// Every class the compiler's own seams compose, in declaration order.
40    ///
41    /// An adopter's declared classes are its own and no roster here enumerates them.
42    pub const ALL: &'static [Self] = &[
43        Self::DeclarationNotRead,
44        Self::PlanNotStated,
45        Self::RenderingNotProduced,
46        Self::RenderingNotClosed,
47        Self::ExplanationNotCovered,
48        Self::MagnitudeNotHeld,
49        Self::ExpansionNotBound,
50        Self::CarrierNotAssembled,
51        Self::CarrierNotDeclared,
52    ];
53
54    /// The class's stable name.
55    #[must_use]
56    pub const fn name(self) -> &'static str {
57        match self {
58            Self::DeclarationNotRead => "declaration-not-read",
59            Self::PlanNotStated => "plan-not-stated",
60            Self::RenderingNotProduced => "rendering-not-produced",
61            Self::RenderingNotClosed => "rendering-not-closed",
62            Self::ExplanationNotCovered => "explanation-not-covered",
63            Self::MagnitudeNotHeld => "magnitude-not-held",
64            Self::ExpansionNotBound => "expansion-not-bound",
65            Self::CarrierNotAssembled => "carrier-not-assembled",
66            Self::CarrierNotDeclared => "carrier-not-declared",
67            Self::Declared { name, .. } => name.spelling(),
68        }
69    }
70
71    /// The second clause of every composed line.
72    #[must_use]
73    pub const fn described(self) -> &'static str {
74        match self {
75            Self::DeclarationNotRead => "the declaration was not read",
76            Self::PlanNotStated => "planning refused",
77            Self::RenderingNotProduced => "the renderer did not produce the planned unit",
78            Self::RenderingNotClosed => {
79                "the rendering does not close over the plan it claims to materialize"
80            }
81            Self::ExplanationNotCovered => "the explanation does not cover its kind's questions",
82            Self::MagnitudeNotHeld => "a rendering would pass a declared magnitude",
83            Self::ExpansionNotBound => "the three values do not belong to one expansion",
84            Self::CarrierNotAssembled => "the closed outputs do not compose into one carrier",
85            Self::CarrierNotDeclared => "the carrier's own vocabulary was not declared",
86            Self::Declared { described, .. } => described,
87        }
88    }
89}
90
91impl Observed {
92    /// Every classification the compiler's own seams state, in declaration order.
93    ///
94    /// An adopter's declared classifications are its own and no roster here enumerates them.
95    pub const ALL: &'static [Self] = &[
96        Self::SeatAbsent,
97        Self::ContractDisagreement,
98        Self::IdentityDisagreement,
99        Self::ProfileDisagreement,
100        Self::BoundExceeded,
101        Self::OriginAbsent,
102    ];
103
104    /// The classification's stable name.
105    #[must_use]
106    pub const fn name(self) -> &'static str {
107        match self {
108            Self::SeatAbsent => "seat-absent",
109            Self::ContractDisagreement => "contract-disagreement",
110            Self::IdentityDisagreement => "identity-disagreement",
111            Self::ProfileDisagreement => "profile-disagreement",
112            Self::BoundExceeded => "bound-exceeded",
113            Self::OriginAbsent => "origin-absent",
114            Self::Declared { name, .. } => name.spelling(),
115        }
116    }
117}
118
119impl core::fmt::Display for DiagnosticNameRefusal {
120    fn fmt(&self, into: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
121        into.write_str(match self {
122            Self::Empty => "a declared diagnostic name is empty",
123            Self::NotKebabCase => "a declared diagnostic name is not lowercase ASCII kebab-case",
124        })
125    }
126}
127
128impl core::error::Error for DiagnosticNameRefusal {}
129
130impl RenderedMagnitude {
131    /// Every declared magnitude a rendering can pass, in declaration order.
132    pub const ALL: &'static [Self] = &[
133        Self::RenderedBytes,
134        Self::RenderedUnits,
135        Self::GeneratedTokens,
136    ];
137
138    /// The magnitude's stable name.
139    #[must_use]
140    pub const fn name(self) -> &'static str {
141        match self {
142            Self::RenderedBytes => "rendered-bytes",
143            Self::RenderedUnits => "rendered-units",
144            Self::GeneratedTokens => "generated-tokens",
145        }
146    }
147
148    /// What the magnitude governs, for the line that says a rendering passed it.
149    #[must_use]
150    pub const fn described(self) -> &'static str {
151        match self {
152            Self::RenderedBytes => "the bytes one rendered unit may carry",
153            Self::RenderedUnits => "the units one rendering may carry",
154            Self::GeneratedTokens => "the tokens one generated tree may carry at one nesting level",
155        }
156    }
157}
158
159impl SiteCoordinate {
160    /// The posture one span table's answer takes.
161    #[must_use]
162    pub const fn answered(answer: Result<SourceCoordinate, SpanResolutionRefusal>) -> Self {
163        match answer {
164            Ok(coordinate) => Self::Resolved(coordinate),
165            Err(refusal) => Self::NotReached(refusal),
166        }
167    }
168
169    /// The resolved coordinate, where the table reached the handle.
170    #[must_use]
171    pub const fn resolved(self) -> Option<SourceCoordinate> {
172        match self {
173            Self::Resolved(coordinate) => Some(coordinate),
174            Self::NotReached(_) => None,
175        }
176    }
177}