1use 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#[derive(Debug, Clone)]
18pub enum LogicErrorKind {
19 CollectionUndefined,
21 UncommitedDescriptor { identifier: Identifier },
23 NoDesigner { identifier: Identifier },
25 ErroneousDesign { identifier: Identifier },
27 ErroneousChecks,
29 UnavailableDesign { identifier: Identifier },
31 LaunchExpectTreatment {
33 wrong_identifier: Option<Identifier>,
34 },
35 LaunchWrongParameter { parameter: String },
37 LaunchTreatmentExpectModel { wrong_identifier: Identifier },
39 NoDirectTrack { id: TrackId },
41 UnexistingVariable {
43 identifier: Identifier,
44 parameter: String,
45 variable: String,
46 },
47 UnexistingContextVariable {
49 identifier: Identifier,
50 parameter: String,
51 context: Identifier,
52 variable: String,
53 },
54 UnexistingParameter {
56 scope: Identifier,
57 called: Identifier,
58 parameter: String,
59 },
60 UnmatchingDataType {
62 scope: Identifier,
63 called: Identifier,
64 parameter: String,
65 value: Value,
66 expected: DescribedType,
67 given: DescribedType,
68 },
69 UnsetParameter {
71 scope: Identifier,
72 called: Identifier,
73 parameter: String,
74 },
75 MultipleParameterAssignation {
77 scope: Identifier,
78 called: Identifier,
79 parameter: String,
80 },
81 NoValue {
83 scope: Identifier,
84 called: Identifier,
85 parameter: String,
86 },
87 NoContext {
89 scope: Identifier,
90 model: Identifier,
91 name: String,
92 parameter: String,
93 },
94 UnavailableContext {
96 scope: Identifier,
97 context: Identifier,
98 },
99 ConnectionInputNotFound {
101 scope: Identifier,
102 to: Identifier,
103 input: String,
104 },
105 ConnectionSelfInputNotFound { scope: Identifier, input: String },
107 ConnectionOutputNotFound {
109 scope: Identifier,
110 from: Identifier,
111 output: String,
112 },
113 ConnectionSelfOutputNotFound { scope: Identifier, output: String },
115 UnexistingTreatment {
117 scope: Identifier,
118 claimed: IdentifierRequirement,
119 },
120 UnexistingModel {
122 scope: Identifier,
123 claimed: IdentifierRequirement,
124 },
125 UnexistingContext {
127 scope: Identifier,
128 claimed: IdentifierRequirement,
129 },
130 UnexistingFunction {
132 scope: Identifier,
133 claimed: IdentifierRequirement,
134 },
135 UnexistingData {
137 scope: Identifier,
138 claimed: IdentifierRequirement,
139 },
140 UndeclaredModel { scope: Identifier, model: String },
142 AlreadyDeclaredModel { scope: Identifier, model: String },
144 UndeclaredTreatment {
146 scope: Identifier,
147 treatment: String,
148 },
149 AlreadyDeclaredTreatment {
151 scope: Identifier,
152 treatment: String,
153 },
154 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 UnsatisfiedOutput { scope: Identifier, output: String },
168 OverloadedOutput { scope: Identifier, output: String },
170 UnmatchingModelType {
172 scope: Identifier,
173 called: Identifier,
174 name: String,
175 expected: Identifier,
176 given_name: String,
177 given: Identifier,
178 },
179 UnexistingParametricModel {
181 scope: Identifier,
182 called: Identifier,
183 parametric_model: String,
184 },
185 UnsetModel {
187 scope: Identifier,
188 called: Identifier,
189 parametric_model: String,
190 },
191 AlreadyIncludedBuildStep {
193 treatment: Identifier,
194 cause_step: CheckStep,
195 check_steps: Vec<CheckStep>,
196 },
197 UnsatisfiedInput {
199 scope: Option<Identifier>,
200 treatment: String,
201 input: String,
202 },
203 OverloadedInput {
205 scope: Identifier,
206 treatment: String,
207 input: String,
208 },
209 ConstRequiredVarProvided {
211 scope: Identifier,
212 called: Identifier,
213 parameter: String,
214 variable: String,
215 },
216 ConstRequiredContextProvided {
218 scope: Identifier,
219 called: Identifier,
220 parameter: String,
221 context: Identifier,
222 entry: String,
223 },
224 ModelInstanciationConstOnly {
226 scope: Identifier,
227 called: Identifier,
228 name: String,
229 parameter: String,
230 },
231 ConstRequiredFunctionReturnsVar {
233 scope: Identifier,
234 called: Identifier,
235 parameter: String,
236 function: Identifier,
237 },
238 UnmatchingNumberOfParameters {
240 scope: Identifier,
241 function: Identifier,
242 },
243 UnexistingGeneric {
245 scope: Identifier,
246 element: Identifier,
247 name: String,
248 described_type: DescribedType,
249 },
250 UndefinedGeneric {
252 scope: Identifier,
253 element: Identifier,
254 described_type: DescribedType,
255 },
256 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#[derive(Debug, Clone)]
347pub struct LogicError {
348 pub id: u32,
350 pub kind: LogicErrorKind,
352 pub design_reference: Option<Arc<dyn Reference>>,
354}
355
356impl LogicError {
357 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}