Skip to main content

sim_expr_tree_calc/calc/face/
model.rs

1use sim_codec::DecodePosition;
2use sim_kernel::EncodePosition;
3
4/// Position recorded beside a source edit or encoded face.
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6pub enum FacePosition {
7    /// Evaluated expression position.
8    Eval,
9    /// Quoted expression position.
10    Quote,
11    /// Inert data position.
12    Data,
13    /// Pattern position.
14    Pattern,
15}
16
17impl From<DecodePosition> for FacePosition {
18    fn from(value: DecodePosition) -> Self {
19        match value {
20            DecodePosition::Eval => Self::Eval,
21            DecodePosition::Quote => Self::Quote,
22            DecodePosition::Data => Self::Data,
23            DecodePosition::Pattern => Self::Pattern,
24        }
25    }
26}
27
28impl From<EncodePosition> for FacePosition {
29    fn from(value: EncodePosition) -> Self {
30        match value {
31            EncodePosition::Eval => Self::Eval,
32            EncodePosition::Quote => Self::Quote,
33            EncodePosition::Data => Self::Data,
34            EncodePosition::Pattern => Self::Pattern,
35        }
36    }
37}
38
39/// Resource dimension that stopped a bounded face operation.
40#[derive(Clone, Copy, Debug, Eq, PartialEq)]
41pub enum FaceDimension {
42    /// Aggregate scalar payload or encoded output bytes.
43    Bytes,
44    /// Expression nesting depth.
45    Depth,
46    /// Expression nodes or runtime collection items.
47    Items,
48}
49
50/// Explicit outcome metadata for source edits and encoded faces.
51#[derive(Clone, Debug, Eq, PartialEq)]
52pub enum FaceIssue {
53    /// The operation completed within every bound.
54    Complete,
55    /// The input or output exceeded one explicit budget.
56    Truncated {
57        /// Budget dimension reached.
58        dimension: FaceDimension,
59        /// Configured maximum.
60        limit: usize,
61        /// First observed value beyond the maximum, or the final encoded size.
62        observed: usize,
63    },
64    /// The selected value or policy has no safe presentation path.
65    Unsupported {
66        /// Stable bounded explanation.
67        reason: String,
68    },
69    /// Codec lookup, decoding, or encoding failed closed.
70    CodecFailure {
71        /// Stable bounded codec diagnostic.
72        message: String,
73    },
74}
75
76/// Metadata carried for every edit and face, including failures.
77#[derive(Clone, Debug, Eq, PartialEq)]
78pub struct FaceMetadata {
79    pub(super) codec: Option<String>,
80    pub(super) position: FacePosition,
81    pub(super) issue: FaceIssue,
82}
83
84impl FaceMetadata {
85    /// Selected codec name, when one was configured.
86    #[must_use]
87    pub fn codec(&self) -> Option<&str> {
88        self.codec.as_deref()
89    }
90
91    /// Explicit decode or encode position.
92    #[must_use]
93    pub const fn position(&self) -> FacePosition {
94        self.position
95    }
96
97    /// Completion, truncation, unsupported-value, or codec-failure metadata.
98    #[must_use]
99    pub const fn issue(&self) -> &FaceIssue {
100        &self.issue
101    }
102
103    /// Whether the operation completed successfully.
104    #[must_use]
105    pub const fn is_complete(&self) -> bool {
106        matches!(self.issue, FaceIssue::Complete)
107    }
108}
109
110/// Encoded face payload.
111#[derive(Clone, Debug, Eq, PartialEq)]
112pub enum FaceContent {
113    /// Text codec output.
114    Text(String),
115    /// Binary codec output.
116    Bytes(Vec<u8>),
117}
118
119/// A bounded presentation face plus explicit outcome metadata.
120#[derive(Clone, Debug, Eq, PartialEq)]
121pub struct EncodedFace {
122    pub(super) content: Option<FaceContent>,
123    pub(super) metadata: FaceMetadata,
124}
125
126impl EncodedFace {
127    /// Encoded payload, absent for every non-complete outcome.
128    #[must_use]
129    pub const fn content(&self) -> Option<&FaceContent> {
130        self.content.as_ref()
131    }
132
133    /// Explicit outcome metadata.
134    #[must_use]
135    pub const fn metadata(&self) -> &FaceMetadata {
136        &self.metadata
137    }
138}
139
140/// Result of applying edited source.
141#[derive(Clone, Debug, Eq, PartialEq)]
142pub struct SourceEditOutcome {
143    pub(super) metadata: FaceMetadata,
144}
145
146impl SourceEditOutcome {
147    /// Whether the decoded source replaced the cell.
148    #[must_use]
149    pub const fn applied(&self) -> bool {
150        self.metadata.is_complete()
151    }
152
153    /// Explicit decode outcome metadata.
154    #[must_use]
155    pub const fn metadata(&self) -> &FaceMetadata {
156        &self.metadata
157    }
158}