Skip to main content

meta_language/
configuration.rs

1/// Trivia attachment strategy.
2#[derive(Clone, Copy, Debug, PartialEq, Eq)]
3pub enum TriviaAttachmentPolicy {
4    /// Attach trivia to the containing syntax link.
5    ContainmentLink,
6    /// Attach trivia to the token link.
7    TokenLink,
8    /// Emit both attachment links when they can coexist.
9    Both,
10}
11
12/// Region detection strategy for mixed-language parsing.
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum RegionDetectionPolicy {
15    /// Use explicit region names such as fenced-code language tags.
16    NameDriven,
17    /// Use content sniffing.
18    ContentDriven,
19    /// Use name-driven detection first and content-driven detection as a fallback.
20    Both,
21}
22
23/// Natural-language identification backend.
24#[derive(Clone, Copy, Debug, PartialEq, Eq)]
25pub enum LanguageIdentificationDetector {
26    /// Use `lingua` for language identification.
27    Lingua,
28    /// Use `whatlang` for language identification.
29    Whatlang,
30}
31
32/// Configured amount of formal meaning to expose during reconstruction.
33#[derive(Clone, Copy, Debug, PartialEq, Eq)]
34pub enum FormalizationLevel {
35    /// Natural surface text in the requested target language.
36    Natural,
37    /// Predicate form using target-language labels where they are available.
38    Lexical,
39    /// Predicate form using shared concept identifiers.
40    Concept,
41    /// Link-like proposition form including the truth marker.
42    Logical,
43}
44
45/// Direction for text/network conversion.
46#[derive(Clone, Copy, Debug, PartialEq, Eq)]
47pub enum NaturalizationDirection {
48    /// Prefer target-language natural text when reconstructing.
49    Naturalize,
50    /// Prefer the configured formal representation when reconstructing.
51    Formalize,
52}
53
54/// Whether the engine produces a mutable network or an enforced read-only one.
55#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
56pub enum AccessMode {
57    /// The network is editable: mutators such as `insert_link` and
58    /// `apply_substitution` are available on `&mut LinkNetwork`.
59    #[default]
60    Mutable,
61    /// The network is frozen: only `&self` operations (query, project,
62    /// reconstruct, verify, serialize) are reachable, and mutation attempts at
63    /// the engine boundary fail with a clear diagnostic.
64    ReadOnly,
65}
66
67impl AccessMode {
68    /// Human-readable access-mode name.
69    #[must_use]
70    pub const fn label(self) -> &'static str {
71        match self {
72            Self::Mutable => "mutable",
73            Self::ReadOnly => "read-only",
74        }
75    }
76
77    /// Whether this access mode permits mutation.
78    #[must_use]
79    pub const fn is_mutable(self) -> bool {
80        matches!(self, Self::Mutable)
81    }
82
83    /// Whether this access mode forbids mutation.
84    #[must_use]
85    pub const fn is_read_only(self) -> bool {
86        matches!(self, Self::ReadOnly)
87    }
88}
89
90/// Configuration for parse-to-network operations.
91#[derive(Clone, Copy, Debug, PartialEq, Eq)]
92pub struct ParseConfiguration {
93    trivia_attachment_policy: TriviaAttachmentPolicy,
94    region_detection_policy: RegionDetectionPolicy,
95    language_identification_detector: LanguageIdentificationDetector,
96    formalization_level: FormalizationLevel,
97    naturalization_direction: NaturalizationDirection,
98    access_mode: AccessMode,
99    profile: Option<&'static str>,
100}
101
102impl ParseConfiguration {
103    /// Creates parse configuration with the supplied trivia policy.
104    #[must_use]
105    pub const fn new(trivia_attachment_policy: TriviaAttachmentPolicy) -> Self {
106        Self {
107            trivia_attachment_policy,
108            region_detection_policy: RegionDetectionPolicy::Both,
109            language_identification_detector: LanguageIdentificationDetector::Lingua,
110            formalization_level: FormalizationLevel::Natural,
111            naturalization_direction: NaturalizationDirection::Naturalize,
112            access_mode: AccessMode::Mutable,
113            profile: None,
114        }
115    }
116
117    /// Returns configuration with a mixed-language region detection policy.
118    #[must_use]
119    pub const fn with_region_detection_policy(
120        mut self,
121        region_detection_policy: RegionDetectionPolicy,
122    ) -> Self {
123        self.region_detection_policy = region_detection_policy;
124        self
125    }
126
127    /// Returns configuration with a natural-language identification backend.
128    #[must_use]
129    pub const fn with_language_identification_detector(
130        mut self,
131        detector: LanguageIdentificationDetector,
132    ) -> Self {
133        self.language_identification_detector = detector;
134        self
135    }
136
137    /// Returns configuration with a formalization detail level.
138    #[must_use]
139    pub const fn with_formalization_level(
140        mut self,
141        formalization_level: FormalizationLevel,
142    ) -> Self {
143        self.formalization_level = formalization_level;
144        self
145    }
146
147    /// Returns configuration with a naturalization/formalization direction.
148    #[must_use]
149    pub const fn with_naturalization_direction(
150        mut self,
151        naturalization_direction: NaturalizationDirection,
152    ) -> Self {
153        self.naturalization_direction = naturalization_direction;
154        self
155    }
156
157    /// Returns configuration with a read-only or mutable engine access mode.
158    #[must_use]
159    pub const fn with_access_mode(mut self, access_mode: AccessMode) -> Self {
160        self.access_mode = access_mode;
161        self
162    }
163
164    /// Returns configuration with a language capability profile name.
165    ///
166    /// Built-in profiles such as `"JavaScript"` are materialized as queryable
167    /// links during parsing. User-declared profiles can be supplied directly to
168    /// transform-time APIs.
169    #[must_use]
170    pub const fn with_profile(mut self, profile: &'static str) -> Self {
171        self.profile = Some(profile);
172        self
173    }
174
175    /// Trivia attachment policy.
176    #[must_use]
177    pub const fn trivia_attachment_policy(self) -> TriviaAttachmentPolicy {
178        self.trivia_attachment_policy
179    }
180
181    /// Mixed-language region detection policy.
182    #[must_use]
183    pub const fn region_detection_policy(self) -> RegionDetectionPolicy {
184        self.region_detection_policy
185    }
186
187    /// Natural-language identification backend.
188    #[must_use]
189    pub const fn language_identification_detector(self) -> LanguageIdentificationDetector {
190        self.language_identification_detector
191    }
192
193    /// Formalization detail level.
194    #[must_use]
195    pub const fn formalization_level(self) -> FormalizationLevel {
196        self.formalization_level
197    }
198
199    /// Naturalization/formalization direction.
200    #[must_use]
201    pub const fn naturalization_direction(self) -> NaturalizationDirection {
202        self.naturalization_direction
203    }
204
205    /// Read-only or mutable engine access mode.
206    #[must_use]
207    pub const fn access_mode(self) -> AccessMode {
208        self.access_mode
209    }
210
211    /// Configured language capability profile name.
212    #[must_use]
213    pub const fn profile(self) -> Option<&'static str> {
214        self.profile
215    }
216}
217
218impl Default for ParseConfiguration {
219    fn default() -> Self {
220        Self::new(TriviaAttachmentPolicy::Both)
221    }
222}