melodium_engine/error/
logic_error.rs

1//! Provides Mélodium logic error management.
2//!
3//! The main type of this module is [`LogicError`], which handles most of the management, combined with kind of errors detailed with [`LogicErrorKind`].
4
5use core::fmt::{Debug, Display};
6use std::string::ToString;
7use std::sync::Arc;
8
9use melodium_common::{
10    descriptor::{DataTrait, DescribedType, Flow, Identifier, IdentifierRequirement, Status},
11    executive::TrackId,
12};
13
14use crate::{building::CheckStep, design::Value, designer::Reference};
15
16/// Kind of logic error that might happen.
17#[derive(Debug, Clone)]
18pub enum LogicErrorKind {
19    /// Designer do not have collection defined.
20    CollectionUndefined,
21    /// Descriptor has not been commited, no designer available yet.
22    UncommitedDescriptor { identifier: Identifier },
23    /// No designer to commit from.
24    NoDesigner { identifier: Identifier },
25    /// Design have some errors, while pure success is expected.
26    ErroneousDesign { identifier: Identifier },
27    /// Checks hasn't all been sucessful, while pure sucess is expected.
28    ErroneousChecks,
29    /// No design available.
30    UnavailableDesign { identifier: Identifier },
31    /// The launch must be done using a treatment.
32    LaunchExpectTreatment {
33        wrong_identifier: Option<Identifier>,
34    },
35    /// A parameter with wrong or missing value was given for launch.
36    LaunchWrongParameter { parameter: String },
37    /// The launch cannot be done through model-requiring treatment.
38    LaunchTreatmentExpectModel { wrong_identifier: Identifier },
39    /// No direct track exist for id.
40    NoDirectTrack { id: TrackId },
41    /// The referenced variable for value doesn't exist.
42    UnexistingVariable {
43        identifier: Identifier,
44        parameter: String,
45        variable: String,
46    },
47    /// The referenced context variable for value doesn't exist.
48    UnexistingContextVariable {
49        identifier: Identifier,
50        parameter: String,
51        context: Identifier,
52        variable: String,
53    },
54    /// The designated parameter doesn't exist in descriptor.
55    UnexistingParameter {
56        scope: Identifier,
57        called: Identifier,
58        parameter: String,
59    },
60    /// The value datatype doesn't match the required one.
61    UnmatchingDataType {
62        scope: Identifier,
63        called: Identifier,
64        parameter: String,
65        value: Value,
66        expected: DescribedType,
67        given: DescribedType,
68    },
69    /// A parameter hasn't been set up compared to descriptor.
70    UnsetParameter {
71        scope: Identifier,
72        called: Identifier,
73        parameter: String,
74    },
75    /// A parameter is assigned multiple times.
76    MultipleParameterAssignation {
77        scope: Identifier,
78        called: Identifier,
79        parameter: String,
80    },
81    /// A parameter didn't get any value.
82    NoValue {
83        scope: Identifier,
84        called: Identifier,
85        parameter: String,
86    },
87    /// No context reference is allowed there.
88    NoContext {
89        scope: Identifier,
90        model: Identifier,
91        name: String,
92        parameter: String,
93    },
94    /// The context referenced is not available in this scope.
95    UnavailableContext {
96        scope: Identifier,
97        context: Identifier,
98    },
99    /// The connection input data is not provided by input treatment.
100    ConnectionInputNotFound {
101        scope: Identifier,
102        to: Identifier,
103        input: String,
104    },
105    /// The connection input data is not provided in self inputs.
106    ConnectionSelfInputNotFound { scope: Identifier, input: String },
107    /// The connection output data is not provided by output treatment.
108    ConnectionOutputNotFound {
109        scope: Identifier,
110        from: Identifier,
111        output: String,
112    },
113    /// The connection output data is not provided in self outputs.
114    ConnectionSelfOutputNotFound { scope: Identifier, output: String },
115    /// The treatment is not existing within current available treatments.
116    UnexistingTreatment {
117        scope: Identifier,
118        claimed: IdentifierRequirement,
119    },
120    /// The model is not existing within current available models.
121    UnexistingModel {
122        scope: Identifier,
123        claimed: IdentifierRequirement,
124    },
125    /// The context is not existing within current available contextes.
126    UnexistingContext {
127        scope: Identifier,
128        claimed: IdentifierRequirement,
129    },
130    /// The function is not existing within current available functions.
131    UnexistingFunction {
132        scope: Identifier,
133        claimed: IdentifierRequirement,
134    },
135    /// The data type is not existing within current available data types.
136    UnexistingData {
137        scope: Identifier,
138        claimed: IdentifierRequirement,
139    },
140    /// The model is not declared here.
141    UndeclaredModel { scope: Identifier, model: String },
142    /// The model name is already declared.
143    AlreadyDeclaredModel { scope: Identifier, model: String },
144    /// The treatment is not declared here.
145    UndeclaredTreatment {
146        scope: Identifier,
147        treatment: String,
148    },
149    /// The treatment name is already declared.
150    AlreadyDeclaredTreatment {
151        scope: Identifier,
152        treatment: String,
153    },
154    /// The connection type is not existing within current available connections.
155    UnexistingConnectionType {
156        scope: Identifier,
157        from: String,
158        output: String,
159        to: String,
160        input: String,
161        output_flow: Flow,
162        output_type: DescribedType,
163        input_flow: Flow,
164        input_type: DescribedType,
165    },
166    /// The sequence output is not currently satisfied, not connected to any treatment output.
167    UnsatisfiedOutput { scope: Identifier, output: String },
168    /// The sequence output is overloaded, having multiple treatment outputs connected to.
169    OverloadedOutput { scope: Identifier, output: String },
170    /// The (core) model type does not match.
171    UnmatchingModelType {
172        scope: Identifier,
173        called: Identifier,
174        name: String,
175        expected: Identifier,
176        given_name: String,
177        given: Identifier,
178    },
179    /// There are no matching pararmetric model.
180    UnexistingParametricModel {
181        scope: Identifier,
182        called: Identifier,
183        parametric_model: String,
184    },
185    /// A model hasn't been set up compared to descriptor.
186    UnsetModel {
187        scope: Identifier,
188        called: Identifier,
189        parametric_model: String,
190    },
191    /// The build step is already included in the call stack, meaning there is an infinite call loop.
192    AlreadyIncludedBuildStep {
193        treatment: Identifier,
194        cause_step: CheckStep,
195        check_steps: Vec<CheckStep>,
196    },
197    /// The treatment input in not satisfied
198    UnsatisfiedInput {
199        scope: Option<Identifier>,
200        treatment: String,
201        input: String,
202    },
203    /// The treatment input is overloaded
204    OverloadedInput {
205        scope: Identifier,
206        treatment: String,
207        input: String,
208    },
209    /// A constant is required but the value assigned is variable
210    ConstRequiredVarProvided {
211        scope: Identifier,
212        called: Identifier,
213        parameter: String,
214        variable: String,
215    },
216    /// A constant is required but a context is provided
217    ConstRequiredContextProvided {
218        scope: Identifier,
219        called: Identifier,
220        parameter: String,
221        context: Identifier,
222        entry: String,
223    },
224    /// A model instanciation can only have const assignations
225    ModelInstanciationConstOnly {
226        scope: Identifier,
227        called: Identifier,
228        name: String,
229        parameter: String,
230    },
231    /// A function returns var when const is expected, due to a var parameter
232    ConstRequiredFunctionReturnsVar {
233        scope: Identifier,
234        called: Identifier,
235        parameter: String,
236        function: Identifier,
237    },
238    /// A function doesn't get the right number of parameters
239    UnmatchingNumberOfParameters {
240        scope: Identifier,
241        function: Identifier,
242    },
243    /// A value is setup for a generic that doesn't exists
244    UnexistingGeneric {
245        scope: Identifier,
246        element: Identifier,
247        name: String,
248        described_type: DescribedType,
249    },
250    /// A generic value is not defined
251    UndefinedGeneric {
252        scope: Identifier,
253        element: Identifier,
254        described_type: DescribedType,
255    },
256    /// Traits are not satisfied
257    UnsatisfiedTraits {
258        scope: Identifier,
259        element: Identifier,
260        described_type: DescribedType,
261        unsatisfied_traits: Vec<DataTrait>,
262    },
263}
264
265impl LogicErrorKind {
266    fn described_type_details(described_type: &DescribedType) -> String {
267        match described_type.final_type() {
268            DescribedType::Data(data) => format!("data type {}", data.identifier()),
269            DescribedType::Generic(generic) => format!("generic {}", generic),
270            dt => dt.to_string(),
271        }
272    }
273}
274
275impl Display for LogicErrorKind {
276    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
277        match self {
278            LogicErrorKind::CollectionUndefined => write!(f, "No collection defined"),
279            LogicErrorKind::UncommitedDescriptor { identifier } => write!(f, "Uncommited descriptor, no designer available for '{identifier}'"),
280            LogicErrorKind::NoDesigner {identifier } => write!(f, "Nothing to commit, as no designer available for '{identifier}'"),
281            LogicErrorKind::ErroneousDesign {identifier} => write!(f, "Design for '{identifier}' contains errors and cannot be commited"),
282            LogicErrorKind::ErroneousChecks => write!(f, "Building coherency checks found errors, build cannot be made"),
283            LogicErrorKind::UnavailableDesign { identifier } => write!(f, "Unavailable design for '{identifier}'"),
284            LogicErrorKind::LaunchExpectTreatment { wrong_identifier } => if let Some(id) = wrong_identifier {
285                write!(f, "Launch must be done using a treatment, '{id}' is not one") } else {
286                    write!(f, "Launch must be done using a treatment, but no valid identifier is provided")
287                },
288            LogicErrorKind::LaunchWrongParameter { parameter } => write!(f, "Parameter '{parameter}' has no valid value for launch"),
289            LogicErrorKind::LaunchTreatmentExpectModel {wrong_identifier} => write!(f, "Launch must be done with a treatment that does not require model, but '{wrong_identifier}' expect some model"),
290            LogicErrorKind::NoDirectTrack { id } => write!(f, "No directly instancied track exist for id {id}"),
291            LogicErrorKind::UnexistingVariable {identifier,
292                parameter,
293                variable,} => write!(f, "Referenced '{variable}' variable for '{parameter}' parameter doesn't exist in '{identifier}'"),
294            LogicErrorKind::UnexistingContextVariable{identifier,
295                parameter,
296                context,
297                variable,} => write!(f, "Referenced '{variable}' context value for '{parameter}' does not exist within '{context}' context in '{identifier}'"),
298            LogicErrorKind::UnexistingParameter {
299                scope,
300                called,
301                parameter,
302            } => write!(f, "Parameter '{parameter}' does not exist for '{called}' in '{scope}'"),
303            LogicErrorKind::UnmatchingDataType {
304                scope, called, parameter, value, expected, given
305            } => write!(f, "Datatype does not match for '{parameter}' of '{called}' in '{scope}', {expected} ({}) expected but '{value}' is {given} ({})", Self::described_type_details(expected), Self::described_type_details(given)),
306            LogicErrorKind::UnsetParameter { scope, called, parameter } => write!(f, "Parameter '{parameter}' of '{called}' is not set in '{scope}'"),
307            LogicErrorKind::MultipleParameterAssignation { scope, called, parameter } => write!(f, "Parameter '{parameter}' of '{called}' assigned multiple times in '{scope}'"),
308            LogicErrorKind::NoValue {scope, called, parameter} => write!(f, "No value assigned to '{parameter}' of '{called}' in '{scope}'"),
309            LogicErrorKind::NoContext{scope, model, name, parameter } => write!(f, "Context used for parameter '{parameter}' of model '{name}' type '{model}' in '{scope}', but context values cannot be used for models"),
310            LogicErrorKind::UnavailableContext{scope, context} => write!(f, "Context '{context}' not available in '{scope}'"),
311            LogicErrorKind::ConnectionInputNotFound{scope: _, to, input} => write!(f, "Input '{input}' is not provided by '{to}'"),
312            LogicErrorKind::ConnectionSelfInputNotFound { scope, input } => write!(f, "Input '{input}' does not exist for '{scope}'"),
313            LogicErrorKind::ConnectionOutputNotFound { scope: _, from, output } => write!(f, "Output '{output}' is not provided by '{from}'"),
314            LogicErrorKind::ConnectionSelfOutputNotFound{scope, output} => write!(f, "Output '{output}' does not exist for '{scope}'"),
315            LogicErrorKind::UnexistingTreatment{scope: _, claimed} => write!(f, "Treatment '{claimed}' does not exist"),
316            LogicErrorKind::UnexistingModel { scope: _, claimed } => write!(f, "Model '{claimed}' does not exist"),
317            LogicErrorKind::UnexistingContext { scope: _, claimed } => write!(f, "Context '{claimed}' does not exist"),
318            LogicErrorKind::UnexistingFunction{ scope: _, claimed } => write!(f, "Function '{claimed}' does not exist"),
319            LogicErrorKind::UnexistingData{ scope: _, claimed } => write!(f, "Data type '{claimed}' does not exist"),
320            LogicErrorKind::UndeclaredModel { scope, model } => write!(f, "Model '{model}' is not declared in '{scope}'"),
321            LogicErrorKind::AlreadyDeclaredModel { scope, model } => write!(f, "Model '{model}' is already declared in '{scope}'"),
322            LogicErrorKind::UndeclaredTreatment { scope, treatment } => write!(f, "Treatment '{treatment}' is not declared in '{scope}'"),
323            LogicErrorKind::AlreadyDeclaredTreatment { scope, treatment } => write!(f, "Treatment '{treatment}' is already declared in '{scope}'"),
324            LogicErrorKind::UnexistingConnectionType { scope, from, output, to, input, output_type, input_type, output_flow, input_flow } => write!(f, "Connection from '{from}' to '{to}' in '{scope}' is not possible, '{output}' is {output_flow}<{output_type}> ({}) but '{input}' is {input_flow}<{input_type}> ({})", Self::described_type_details(output_type), Self::described_type_details(input_type)),
325            LogicErrorKind::UnsatisfiedOutput { scope, output } => write!(f, "Output '{output}' is not satisfied in '{scope}'"),
326            LogicErrorKind::OverloadedOutput { scope, output } => write!(f, "Output '{output}' is overloaded in '{scope}', only one connection is possible to 'Self' outputs"),
327            LogicErrorKind::UnmatchingModelType { scope: _, called, name, expected, given_name, given } => write!(f, "Model '{name}' for '{called}' is expected to be '{expected}', but given '{given_name}' is '{given}' and not based on it"),
328            LogicErrorKind::UnexistingParametricModel { scope, called, parametric_model } => write!(f, "Parametric model '{parametric_model}' does not exist for '{called}' in '{scope}'"),
329            LogicErrorKind::UnsetModel { scope, called, parametric_model } => write!(f, "No model assigned to '{parametric_model}' of '{called}' in '{scope}'"),
330            LogicErrorKind::AlreadyIncludedBuildStep { treatment , cause_step,check_steps}  => write!(f, "Treatment '{treatment}' is referring to same instanciation of itself, causing infinite connection loop ({cause_step} already present in {})", check_steps.iter().map(|cs| cs.to_string()).collect::<Vec<_>>().join(", ")),
331            LogicErrorKind::UnsatisfiedInput { scope, treatment, input } => if let Some(id) = scope {write!(f, "Input '{input}' of '{treatment}' is not satisfied in '{id}'")} else {write!(f, "Entrypoint have input '{input}' that must be satisfied")},
332            LogicErrorKind::OverloadedInput { scope, treatment, input } => write!(f, "Input '{input}' of '{treatment}' is overloaded in '{scope}'"),
333            LogicErrorKind::ConstRequiredVarProvided { scope, called, parameter, variable } => write!(f, "Parameter '{parameter}' of '{called}' is constant but provided '{variable}' is variable in '{scope}'"),
334            LogicErrorKind::ConstRequiredContextProvided { scope, called, parameter, context, entry: _ } => write!(f, "Parameter '{parameter}' of '{called}' is constant but context '{context}' is provided in '{scope}', contexts are implicitly variable"),
335            LogicErrorKind::ModelInstanciationConstOnly { scope, called, name, parameter } => write!(f, "Variable provided for parameter '{parameter}' of model '{name}' from type '{called}' in '{scope}', model instanciations can only get constants"),
336            LogicErrorKind::ConstRequiredFunctionReturnsVar { scope, called, parameter, function } => write!(f, "Parameter '{parameter}' of '{called}' is constant but provided '{function}' have variable return value in '{scope}'"),
337            LogicErrorKind::UnmatchingNumberOfParameters { scope, function } => write!(f, "Number of parameters given do not match for function '{function}' in '{scope}'"),
338            LogicErrorKind::UnexistingGeneric { scope, element, name, described_type } => write!(f, "The generic type '{name}' ({}) doesn't exist for '{element}' in '{scope}'", Self::described_type_details(described_type)),
339            LogicErrorKind::UndefinedGeneric { scope, element, described_type } => write!(f, "Generic '{described_type}' ({}) is not defined for '{element}' in '{scope}'", Self::described_type_details(described_type)),
340            LogicErrorKind::UnsatisfiedTraits { scope, element, described_type, unsatisfied_traits } => write!(f, "Type '{described_type}' ({}) does not satisfy trait {} for '{element}' in '{scope}'", Self::described_type_details(described_type), unsatisfied_traits.iter().map(|tr| tr.to_string()).collect::<Vec<_>>().join(" + ")),
341        }
342    }
343}
344
345/// Handles and describe a Mélodium logic error.
346#[derive(Debug, Clone)]
347pub struct LogicError {
348    /// Identifier of error.
349    pub id: u32,
350    /// Kind of error.
351    pub kind: LogicErrorKind,
352    /// Optional design reference attached to error.
353    pub design_reference: Option<Arc<dyn Reference>>,
354}
355
356impl LogicError {
357    /// Generates a new error with [`LogicErrorKind::CollectionUndefined`] kind.
358    pub fn collection_undefined(id: u32, design_reference: Option<Arc<dyn Reference>>) -> Self {
359        Self {
360            id,
361            design_reference,
362            kind: LogicErrorKind::CollectionUndefined,
363        }
364    }
365
366    /// Generates a new error with [`LogicErrorKind::UncommitedDescriptor`] kind.
367    pub fn uncommited_descriptor(
368        id: u32,
369        identifier: Identifier,
370        design_reference: Option<Arc<dyn Reference>>,
371    ) -> Self {
372        Self {
373            id,
374            design_reference,
375            kind: LogicErrorKind::UncommitedDescriptor { identifier },
376        }
377    }
378
379    /// Generates a new error with [`LogicErrorKind::NoDesigner`] kind.
380    pub fn no_designer(
381        id: u32,
382        identifier: Identifier,
383        design_reference: Option<Arc<dyn Reference>>,
384    ) -> Self {
385        Self {
386            id,
387            design_reference,
388            kind: LogicErrorKind::NoDesigner { identifier },
389        }
390    }
391
392    /// Generates a new error with [`LogicErrorKind::ErroneousDesign`] kind.
393    pub fn erroneous_design(
394        id: u32,
395        identifier: Identifier,
396        design_reference: Option<Arc<dyn Reference>>,
397    ) -> Self {
398        Self {
399            id,
400            design_reference,
401            kind: LogicErrorKind::ErroneousDesign { identifier },
402        }
403    }
404
405    /// Generates a new error with [`LogicErrorKind::ErroneousChecks`] kind.
406    pub fn erroneous_checks(id: u32, design_reference: Option<Arc<dyn Reference>>) -> Self {
407        Self {
408            id,
409            design_reference,
410            kind: LogicErrorKind::ErroneousChecks,
411        }
412    }
413
414    /// Generates a new error with [`LogicErrorKind::UnavailableDesign`] kind.
415    pub fn unavailable_design(
416        id: u32,
417        identifier: Identifier,
418        design_reference: Option<Arc<dyn Reference>>,
419    ) -> Self {
420        Self {
421            id,
422            design_reference,
423            kind: LogicErrorKind::UnavailableDesign { identifier },
424        }
425    }
426
427    /// Generates a new error with [`LogicErrorKind::LaunchExpectTreatment`] kind.
428    pub fn launch_expect_treatment(id: u32, wrong_identifier: Option<Identifier>) -> Self {
429        Self {
430            id,
431            design_reference: None,
432            kind: LogicErrorKind::LaunchExpectTreatment { wrong_identifier },
433        }
434    }
435
436    pub fn launch_wrong_parameter(id: u32, parameter: String) -> Self {
437        Self {
438            id,
439            design_reference: None,
440            kind: LogicErrorKind::LaunchWrongParameter { parameter },
441        }
442    }
443
444    /// Generates a new error with [`LogicErrorKind::LaunchTreatmentExpectModel`] kind.
445    pub fn launch_treatment_expect_model(id: u32, wrong_identifier: Identifier) -> Self {
446        Self {
447            id,
448            design_reference: None,
449            kind: LogicErrorKind::LaunchTreatmentExpectModel { wrong_identifier },
450        }
451    }
452
453    pub fn no_direct_track(id: u32, track_id: TrackId) -> Self {
454        Self {
455            id,
456            design_reference: None,
457            kind: LogicErrorKind::NoDirectTrack { id: track_id },
458        }
459    }
460
461    /// Generates a new error with [`LogicErrorKind::UnexistingVariable`] kind.
462    pub fn unexisting_variable(
463        id: u32,
464        identifier: Identifier,
465        parameter: String,
466        variable: String,
467        design_reference: Option<Arc<dyn Reference>>,
468    ) -> Self {
469        Self {
470            id,
471            design_reference,
472            kind: LogicErrorKind::UnexistingVariable {
473                identifier,
474                parameter,
475                variable,
476            },
477        }
478    }
479
480    /// Generates a new error with [`LogicErrorKind::UnexistingContextVariable`] kind.
481    pub fn unexisting_context_variable(
482        id: u32,
483        identifier: Identifier,
484        parameter: String,
485        context: Identifier,
486        variable: String,
487        design_reference: Option<Arc<dyn Reference>>,
488    ) -> Self {
489        Self {
490            id,
491            design_reference,
492            kind: LogicErrorKind::UnexistingContextVariable {
493                identifier,
494                parameter,
495                context,
496                variable,
497            },
498        }
499    }
500
501    /// Generates a new error with [`LogicErrorKind::UnexistingParameter`] kind.
502    pub fn unexisting_parameter(
503        id: u32,
504        scope: Identifier,
505        called: Identifier,
506        parameter: String,
507        design_reference: Option<Arc<dyn Reference>>,
508    ) -> Self {
509        Self {
510            id,
511            design_reference,
512            kind: LogicErrorKind::UnexistingParameter {
513                scope,
514                called,
515                parameter,
516            },
517        }
518    }
519
520    /// Generates a new error with [`LogicErrorKind::UnmatchingDataType`] kind.
521    pub fn unmatching_datatype(
522        id: u32,
523        scope: Identifier,
524        called: Identifier,
525        parameter: String,
526        value: Value,
527        expected: DescribedType,
528        given: DescribedType,
529        design_reference: Option<Arc<dyn Reference>>,
530    ) -> Self {
531        Self {
532            id,
533            design_reference,
534            kind: LogicErrorKind::UnmatchingDataType {
535                scope,
536                called,
537                parameter,
538                value,
539                expected,
540                given,
541            },
542        }
543    }
544
545    /// Generates a new error with [`LogicErrorKind::UnsetParameter`] kind.
546    pub fn unset_parameter(
547        id: u32,
548        scope: Identifier,
549        called: Identifier,
550        parameter: String,
551        design_reference: Option<Arc<dyn Reference>>,
552    ) -> Self {
553        Self {
554            id,
555            design_reference,
556            kind: LogicErrorKind::UnsetParameter {
557                scope,
558                called,
559                parameter,
560            },
561        }
562    }
563
564    /// Generates a new error with [`LogicErrorKind::MultipleParameterAssignation`] kind.
565    pub fn multiple_parameter_assignation(
566        id: u32,
567        scope: Identifier,
568        called: Identifier,
569        parameter: String,
570        design_reference: Option<Arc<dyn Reference>>,
571    ) -> Self {
572        Self {
573            id,
574            design_reference,
575            kind: LogicErrorKind::MultipleParameterAssignation {
576                scope,
577                called,
578                parameter,
579            },
580        }
581    }
582
583    /// Generates a new error with [`LogicErrorKind::NoValue`] kind.
584    pub fn no_value(
585        id: u32,
586        scope: Identifier,
587        called: Identifier,
588        parameter: String,
589        design_reference: Option<Arc<dyn Reference>>,
590    ) -> Self {
591        Self {
592            id,
593            design_reference,
594            kind: LogicErrorKind::NoValue {
595                scope,
596                called,
597                parameter,
598            },
599        }
600    }
601
602    /// Generates a new error with [`LogicErrorKind::NoContext`] kind.
603    pub fn no_context(
604        id: u32,
605        scope: Identifier,
606        model: Identifier,
607        name: String,
608        parameter: String,
609        design_reference: Option<Arc<dyn Reference>>,
610    ) -> Self {
611        Self {
612            id,
613            design_reference,
614            kind: LogicErrorKind::NoContext {
615                scope,
616                model,
617                name,
618                parameter,
619            },
620        }
621    }
622
623    /// Generates a new error with [`LogicErrorKind::UnavailableContext`] kind.
624    pub fn unavailable_context(
625        id: u32,
626        scope: Identifier,
627        context: Identifier,
628        design_reference: Option<Arc<dyn Reference>>,
629    ) -> Self {
630        Self {
631            id,
632            design_reference,
633            kind: LogicErrorKind::UnavailableContext { scope, context },
634        }
635    }
636
637    /// Generates a new error with [`LogicErrorKind::ConnectionInputNotFound`] kind.
638    pub fn connection_input_not_found(
639        id: u32,
640        scope: Identifier,
641        to: Identifier,
642        input: String,
643        design_reference: Option<Arc<dyn Reference>>,
644    ) -> Self {
645        Self {
646            id,
647            design_reference,
648            kind: LogicErrorKind::ConnectionInputNotFound { scope, to, input },
649        }
650    }
651
652    /// Generates a new error with [`LogicErrorKind::ConnectionSelfInputNotFound`] kind.
653    pub fn connection_self_input_not_found(
654        id: u32,
655        scope: Identifier,
656        input: String,
657        design_reference: Option<Arc<dyn Reference>>,
658    ) -> Self {
659        Self {
660            id,
661            design_reference,
662            kind: LogicErrorKind::ConnectionSelfInputNotFound { scope, input },
663        }
664    }
665
666    /// Generates a new error with [`LogicErrorKind::ConnectionOutputNotFound`] kind.
667    pub fn connection_output_not_found(
668        id: u32,
669        scope: Identifier,
670        from: Identifier,
671        output: String,
672        design_reference: Option<Arc<dyn Reference>>,
673    ) -> Self {
674        Self {
675            id,
676            design_reference,
677            kind: LogicErrorKind::ConnectionOutputNotFound {
678                scope,
679                from,
680                output,
681            },
682        }
683    }
684
685    /// Generates a new error with [`LogicErrorKind::ConnectionSelfOutputNotFound`] kind.
686    pub fn connection_self_output_not_found(
687        id: u32,
688        scope: Identifier,
689        output: String,
690        design_reference: Option<Arc<dyn Reference>>,
691    ) -> Self {
692        Self {
693            id,
694            design_reference,
695            kind: LogicErrorKind::ConnectionSelfOutputNotFound { scope, output },
696        }
697    }
698
699    /// Generates a new error with [`LogicErrorKind::UnexistingTreatment`] kind.
700    pub fn unexisting_treatment(
701        id: u32,
702        scope: Identifier,
703        claimed: IdentifierRequirement,
704        design_reference: Option<Arc<dyn Reference>>,
705    ) -> Self {
706        Self {
707            id,
708            design_reference,
709            kind: LogicErrorKind::UnexistingTreatment { scope, claimed },
710        }
711    }
712
713    /// Generates a new error with [`LogicErrorKind::UnexistingModel`] kind.
714    pub fn unexisting_model(
715        id: u32,
716        scope: Identifier,
717        claimed: IdentifierRequirement,
718        design_reference: Option<Arc<dyn Reference>>,
719    ) -> Self {
720        Self {
721            id,
722            design_reference,
723            kind: LogicErrorKind::UnexistingModel { scope, claimed },
724        }
725    }
726
727    /// Generates a new error with [`LogicErrorKind::UnexistingContext`] kind.
728    pub fn unexisting_context(
729        id: u32,
730        scope: Identifier,
731        claimed: IdentifierRequirement,
732        design_reference: Option<Arc<dyn Reference>>,
733    ) -> Self {
734        Self {
735            id,
736            design_reference,
737            kind: LogicErrorKind::UnexistingContext { scope, claimed },
738        }
739    }
740
741    /// Generates a new error with [`LogicErrorKind::UnexistingFunction`] kind.
742    pub fn unexisting_function(
743        id: u32,
744        scope: Identifier,
745        claimed: IdentifierRequirement,
746        design_reference: Option<Arc<dyn Reference>>,
747    ) -> Self {
748        Self {
749            id,
750            design_reference,
751            kind: LogicErrorKind::UnexistingFunction { scope, claimed },
752        }
753    }
754
755    /// Generates a new error with [`LogicErrorKind::UnexistingData`] kind.
756    pub fn unexisting_data(
757        id: u32,
758        scope: Identifier,
759        claimed: IdentifierRequirement,
760        design_reference: Option<Arc<dyn Reference>>,
761    ) -> Self {
762        Self {
763            id,
764            design_reference,
765            kind: LogicErrorKind::UnexistingData { scope, claimed },
766        }
767    }
768
769    /// Generates a new error with [`LogicErrorKind::UndeclaredModel`] kind.
770    pub fn undeclared_model(
771        id: u32,
772        scope: Identifier,
773        model: String,
774        design_reference: Option<Arc<dyn Reference>>,
775    ) -> Self {
776        Self {
777            id,
778            design_reference,
779            kind: LogicErrorKind::UndeclaredModel { scope, model },
780        }
781    }
782
783    /// Generates a new error with [`LogicErrorKind::AlreadyDeclaredModel`] kind.
784    pub fn already_declared_model(
785        id: u32,
786        scope: Identifier,
787        model: String,
788        design_reference: Option<Arc<dyn Reference>>,
789    ) -> Self {
790        Self {
791            id,
792            design_reference,
793            kind: LogicErrorKind::AlreadyDeclaredModel { scope, model },
794        }
795    }
796
797    /// Generates a new error with [`LogicErrorKind::UndeclaredTreatment`] kind.
798    pub fn undeclared_treatment(
799        id: u32,
800        scope: Identifier,
801        treatment: String,
802        design_reference: Option<Arc<dyn Reference>>,
803    ) -> Self {
804        Self {
805            id,
806            design_reference,
807            kind: LogicErrorKind::UndeclaredTreatment { scope, treatment },
808        }
809    }
810
811    /// Generates a new error with [`LogicErrorKind::AlreadyDeclaredTreatment`] kind.
812    pub fn already_declared_treatment(
813        id: u32,
814        scope: Identifier,
815        treatment: String,
816        design_reference: Option<Arc<dyn Reference>>,
817    ) -> Self {
818        Self {
819            id,
820            design_reference,
821            kind: LogicErrorKind::AlreadyDeclaredTreatment { scope, treatment },
822        }
823    }
824
825    /// Generates a new error with [`LogicErrorKind::UnexistingConnectionType`] kind.
826    pub fn unexisting_connexion_type(
827        id: u32,
828        scope: Identifier,
829        from: String,
830        output: String,
831        to: String,
832        input: String,
833        output_flow: Flow,
834        output_type: DescribedType,
835        input_flow: Flow,
836        input_type: DescribedType,
837        design_reference: Option<Arc<dyn Reference>>,
838    ) -> Self {
839        Self {
840            id,
841            design_reference,
842            kind: LogicErrorKind::UnexistingConnectionType {
843                scope,
844                from,
845                output,
846                to,
847                input,
848                output_flow,
849                output_type,
850                input_flow,
851                input_type,
852            },
853        }
854    }
855
856    /// Generates a new error with [`LogicErrorKind::UnsatisfiedOutput`] kind.
857    pub fn unsatisfied_output(
858        id: u32,
859        scope: Identifier,
860        output: String,
861        design_reference: Option<Arc<dyn Reference>>,
862    ) -> Self {
863        Self {
864            id,
865            design_reference,
866            kind: LogicErrorKind::UnsatisfiedOutput { scope, output },
867        }
868    }
869
870    /// Generates a new error with [`LogicErrorKind::OverloadedOutput`] kind.
871    pub fn overloaded_output(
872        id: u32,
873        scope: Identifier,
874        output: String,
875        design_reference: Option<Arc<dyn Reference>>,
876    ) -> Self {
877        Self {
878            id,
879            design_reference,
880            kind: LogicErrorKind::OverloadedOutput { scope, output },
881        }
882    }
883
884    /// Generates a new error with [`LogicErrorKind::UnmatchingModelType`] kind.
885    pub fn unmatching_model_type(
886        id: u32,
887        scope: Identifier,
888        called: Identifier,
889        name: String,
890        expected: Identifier,
891        given_name: String,
892        given: Identifier,
893        design_reference: Option<Arc<dyn Reference>>,
894    ) -> Self {
895        Self {
896            id,
897            design_reference,
898            kind: LogicErrorKind::UnmatchingModelType {
899                scope,
900                called,
901                name,
902                expected,
903                given_name,
904                given,
905            },
906        }
907    }
908
909    /// Generates a new error with [`LogicErrorKind::UnexistingParametricModel`] kind.
910    pub fn unexisting_parametric_model(
911        id: u32,
912        scope: Identifier,
913        called: Identifier,
914        parametric_model: String,
915        design_reference: Option<Arc<dyn Reference>>,
916    ) -> Self {
917        Self {
918            id,
919            design_reference,
920            kind: LogicErrorKind::UnexistingParametricModel {
921                scope,
922                called,
923                parametric_model,
924            },
925        }
926    }
927
928    /// Generates a new error with [`LogicErrorKind::UnsetModel`] kind.
929    pub fn unset_model(
930        id: u32,
931        scope: Identifier,
932        called: Identifier,
933        parametric_model: String,
934        design_reference: Option<Arc<dyn Reference>>,
935    ) -> Self {
936        Self {
937            id,
938            design_reference,
939            kind: LogicErrorKind::UnsetModel {
940                scope,
941                called,
942                parametric_model,
943            },
944        }
945    }
946
947    /// Generates a new error with [`LogicErrorKind::AlreadyIncludedBuildStep`] kind.
948    pub fn already_included_build_step(
949        id: u32,
950        treatment: Identifier,
951        cause_step: CheckStep,
952        check_steps: Vec<CheckStep>,
953        design_reference: Option<Arc<dyn Reference>>,
954    ) -> Self {
955        Self {
956            id,
957            design_reference,
958            kind: LogicErrorKind::AlreadyIncludedBuildStep {
959                treatment,
960                cause_step,
961                check_steps,
962            },
963        }
964    }
965
966    /// Generates a new error with [`LogicErrorKind::UnsatisfiedInput`] kind.
967    pub fn unsatisfied_input(
968        id: u32,
969        scope: Option<Identifier>,
970        treatment: String,
971        input: String,
972        design_reference: Option<Arc<dyn Reference>>,
973    ) -> Self {
974        Self {
975            id,
976            design_reference,
977            kind: LogicErrorKind::UnsatisfiedInput {
978                scope,
979                treatment,
980                input,
981            },
982        }
983    }
984
985    /// Generates a new error with [`LogicErrorKind::OverloadedInput`] kind.
986    pub fn overloaded_input(
987        id: u32,
988        scope: Identifier,
989        treatment: String,
990        input: String,
991        design_reference: Option<Arc<dyn Reference>>,
992    ) -> Self {
993        Self {
994            id,
995            design_reference,
996            kind: LogicErrorKind::OverloadedInput {
997                scope,
998                treatment,
999                input,
1000            },
1001        }
1002    }
1003
1004    /// Generates a new error with [`LogicErrorKind::ConstRequiredVarProvided`] kind.
1005    pub fn const_required_var_provided(
1006        id: u32,
1007        scope: Identifier,
1008        called: Identifier,
1009        parameter: String,
1010        variable: String,
1011        design_reference: Option<Arc<dyn Reference>>,
1012    ) -> Self {
1013        Self {
1014            id,
1015            design_reference,
1016            kind: LogicErrorKind::ConstRequiredVarProvided {
1017                scope,
1018                called,
1019                parameter,
1020                variable,
1021            },
1022        }
1023    }
1024
1025    /// Generates a new error with [`LogicErrorKind::ConstRequiredContextProvided`] kind.
1026    pub fn const_required_context_provided(
1027        id: u32,
1028        scope: Identifier,
1029        called: Identifier,
1030        parameter: String,
1031        context: Identifier,
1032        entry: String,
1033        design_reference: Option<Arc<dyn Reference>>,
1034    ) -> Self {
1035        Self {
1036            id,
1037            design_reference,
1038            kind: LogicErrorKind::ConstRequiredContextProvided {
1039                scope,
1040                called,
1041                parameter,
1042                context,
1043                entry,
1044            },
1045        }
1046    }
1047
1048    /// Generates a new error with [`LogicErrorKind::ModelInstanciationConstOnly`] kind.
1049    pub fn model_instanciation_const_only(
1050        id: u32,
1051        scope: Identifier,
1052        called: Identifier,
1053        name: String,
1054        parameter: String,
1055        design_reference: Option<Arc<dyn Reference>>,
1056    ) -> Self {
1057        Self {
1058            id,
1059            design_reference,
1060            kind: LogicErrorKind::ModelInstanciationConstOnly {
1061                scope,
1062                called,
1063                name,
1064                parameter,
1065            },
1066        }
1067    }
1068
1069    /// Generates a new error with [`LogicErrorKind::ConstRequiredFunctionReturnsVar`] kind.
1070    pub fn const_required_function_returns_var(
1071        id: u32,
1072        scope: Identifier,
1073        called: Identifier,
1074        parameter: String,
1075        function: Identifier,
1076        design_reference: Option<Arc<dyn Reference>>,
1077    ) -> Self {
1078        Self {
1079            id,
1080            design_reference,
1081            kind: LogicErrorKind::ConstRequiredFunctionReturnsVar {
1082                scope,
1083                called,
1084                parameter,
1085                function,
1086            },
1087        }
1088    }
1089
1090    /// Generates a new error with [`LogicErrorKind::UnmatchingNumberOfParameters`] kind.
1091    pub fn unmatching_number_of_parameters(
1092        id: u32,
1093        scope: Identifier,
1094        function: Identifier,
1095        design_reference: Option<Arc<dyn Reference>>,
1096    ) -> Self {
1097        Self {
1098            id,
1099            design_reference,
1100            kind: LogicErrorKind::UnmatchingNumberOfParameters { scope, function },
1101        }
1102    }
1103
1104    /// Generates a new error with [`LogicErrorKind::UnexistingGeneric`] kind.
1105    pub fn unexisting_generic(
1106        id: u32,
1107        scope: Identifier,
1108        element: Identifier,
1109        name: String,
1110        described_type: DescribedType,
1111        design_reference: Option<Arc<dyn Reference>>,
1112    ) -> Self {
1113        Self {
1114            id,
1115            design_reference,
1116            kind: LogicErrorKind::UnexistingGeneric {
1117                scope,
1118                element,
1119                name,
1120                described_type,
1121            },
1122        }
1123    }
1124
1125    /// Generates a new error with [`LogicErrorKind::UndefinedGeneric`] kind.
1126    pub fn undefined_generic(
1127        id: u32,
1128        scope: Identifier,
1129        element: Identifier,
1130        described_type: DescribedType,
1131        design_reference: Option<Arc<dyn Reference>>,
1132    ) -> Self {
1133        Self {
1134            id,
1135            design_reference,
1136            kind: LogicErrorKind::UndefinedGeneric {
1137                scope,
1138                element,
1139                described_type,
1140            },
1141        }
1142    }
1143
1144    /// Generates a new error with [`LogicErrorKind::UnsatisfiedTraits`] kind.
1145    pub fn unsatisfied_traits(
1146        id: u32,
1147        scope: Identifier,
1148        element: Identifier,
1149        described_type: DescribedType,
1150        unsatisfied_traits: Vec<DataTrait>,
1151        design_reference: Option<Arc<dyn Reference>>,
1152    ) -> Self {
1153        Self {
1154            id,
1155            design_reference,
1156            kind: LogicErrorKind::UnsatisfiedTraits {
1157                scope,
1158                element,
1159                described_type,
1160                unsatisfied_traits,
1161            },
1162        }
1163    }
1164}
1165
1166impl Display for LogicError {
1167    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1168        write!(f, "D{:04}: {}", self.id, self.kind)
1169    }
1170}
1171
1172pub type LogicErrors = Vec<LogicError>;
1173pub type LogicResult<T> = Status<T, LogicError, LogicError>;
1174
1175impl From<LogicError> for LogicErrors {
1176    fn from(value: LogicError) -> Self {
1177        vec![value]
1178    }
1179}