dsntk_model/
model.rs

1//! # DMN model
2//!
3//! Model for Decision Requirements Graph (DRG)
4//! depicted in one or more Decision Requirements Diagrams (DRD).
5
6use crate::errors::*;
7use dsntk_common::{gen_id, DsntkError, HRef, Result, Uri};
8use dsntk_feel::{FeelType, Name};
9use std::fmt;
10use std::fmt::Display;
11use std::slice::Iter;
12
13pub enum DmnVersion {
14  V13,
15  V14,
16  V15,
17}
18
19/// [DmnId] defines possible types of unique identifiers in model.
20///
21/// Specification defines this identifier as optional, so when this identifier
22/// is not provided in the model, a new unique UUID identifier is generated.
23/// This SHALL not be conflicting with any other identifier.
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum DmnId {
26  /// Identifier was provided in model.
27  Provided(String),
28  /// Identifier was generated during parsing (not provided in model).
29  Generated(String),
30}
31
32/// [DmnElement] is the abstract superclass for the Decision Model elements.
33/// It provides the optional attributes `id`, `description` and `label`,
34/// which other elements will inherit.
35pub trait DmnElement {
36  /// Namespace the element belongs to.
37  fn namespace(&self) -> &str;
38  /// Name of the model the element was defined in.
39  fn model_name(&self) -> &str;
40  /// Returns a reference to identifier for this [DmnElement].
41  /// This identifier SHALL be unique within its containing [Definitions] element.
42  fn id(&self) -> &String;
43  /// Returns a reference to optional identifier for this [DmnElement].
44  fn opt_id(&self) -> Option<&String>;
45  /// Returns reference to optional description of this [DmnElement].
46  fn description(&self) -> &Option<String>;
47  /// Returns reference to optional alternative short description of this [DmnElement].
48  fn label(&self) -> &Option<String>;
49  /// Returns reference to attached additional elements to any [DmnElement].
50  fn extension_elements(&self) -> &Vec<ExtensionElement>;
51  /// Returns reference to attached named extended attributes and model associations to any [DmnElement].
52  fn extension_attributes(&self) -> &Vec<ExtensionAttribute>;
53}
54
55/// [NamedElement] adds attribute `name` to [DmnElement].
56/// `name` attribute is required for [NamedElement].
57pub trait NamedElement: DmnElement {
58  /// Returns the name of this [NamedElement].
59  fn name(&self) -> &str;
60  /// Returns the `FEEL` name for this element.
61  fn feel_name(&self) -> &Name;
62}
63
64/// [Expression] is an abstract class that describes the logic
65/// by which a modeled decision shall be made, or pieces of that logic.
66pub trait Expression {
67  /// Optional namespace-prefixed name of the base type of this [Expression].
68  fn type_ref(&self) -> &Option<String>;
69}
70
71/// [FeelTypedElement] adds the `FEEL` type attributes to element.
72pub trait FeelTypedElement {
73  /// Returns the optional `FEEL` type for this element.
74  fn feel_type(&self) -> &Option<FeelType>;
75  /// Sets `FEEL` type for this element.
76  fn set_feel_type(&mut self, feel_type: FeelType);
77}
78
79/// [RequiredTypeRef] adds the required type reference to element.
80pub trait RequiredTypeRef {
81  /// Namespace-prefixed name of the base type of the implementor.
82  fn type_ref(&self) -> &str;
83}
84
85/// [RequiredVariable] adds the required reference to [InformationItem].
86pub trait RequiredVariable {
87  /// Returns the reference to [InformationItem].
88  fn variable(&self) -> &InformationItem;
89}
90
91/// `Invocable` is used to model the inputs of a decision whose values
92/// are defined outside the decision model.
93pub trait Invocable: DmnElement + NamedElement + RequiredVariable {}
94
95/// The abstract class [BusinessContextElement].
96///
97/// The abstract class [BusinessContextElement], and its concrete specializations
98/// [PerformanceIndicator] and [OrganizationUnit] are placeholders,
99/// anticipating a definition to be adopted from other OMG metamodels,
100/// such as OMG OSM when it is further developed.
101pub trait BusinessContextElement: NamedElement {
102  /// The URI of this [BusinessContextElement].
103  fn uri(&self) -> &Option<String>;
104}
105
106/// The [ExtensionElement] contains element from other
107/// metamodels inside any [DmnElement].
108///
109/// Not used, prepared for further development.
110#[derive(Debug, Clone, PartialEq, Eq)]
111pub struct ExtensionElement;
112
113/// The [ExtensionAttribute] element.
114///
115/// The [ExtensionAttribute] element contains an [ExtensionElement]
116/// or a reference to an [ExtensionElement] from another metamodel.
117/// An [ExtensionAttribute] also has a name
118/// to define the role or purpose of the associated element.
119///
120/// Not used, prepared for further development.
121#[derive(Debug, Clone, PartialEq, Eq)]
122pub struct ExtensionAttribute;
123
124/// Enumeration of concrete instances of [BusinessContextElement].
125#[derive(Debug, Clone)]
126pub enum BusinessContextElementInstance {
127  PerformanceIndicator(PerformanceIndicator),
128  OrganizationUnit(OrganizationUnit),
129}
130
131/// [PerformanceIndicator] is a placeholder, anticipating a definition to be
132/// adopted from other OMG metamodels, such as OMG OSM when it is further developed.
133#[named_element]
134#[dmn_element]
135#[business_context_element]
136#[derive(Debug, Clone)]
137pub struct PerformanceIndicator {
138  /// Collection of [Decision] that impact this [PerformanceIndicator].
139  /// This attribute stores references
140  pub(crate) impacting_decisions: Vec<HRef>,
141}
142
143impl PerformanceIndicator {
144  pub fn impacting_decisions(&self) -> &Vec<HRef> {
145    &self.impacting_decisions
146  }
147}
148
149/// [OrganizationUnit] is a placeholder, anticipating a definition to be
150/// adopted from other OMG metamodels, such as OMG OSM when it is further developed.
151#[named_element]
152#[dmn_element]
153#[business_context_element]
154#[derive(Debug, Clone)]
155pub struct OrganizationUnit {
156  /// Collection of [Decision] that are made by this [OrganizationUnit].
157  pub(crate) decisions_made: Vec<HRef>,
158  /// Collection of [Decision] that are owned by this [OrganizationUnit].
159  pub(crate) decisions_owned: Vec<HRef>,
160}
161
162impl OrganizationUnit {
163  pub fn decisions_made(&self) -> &Vec<HRef> {
164    &self.decisions_made
165  }
166  pub fn decisions_owned(&self) -> &Vec<HRef> {
167    &self.decisions_owned
168  }
169}
170
171/// In DMN model, the [DrgElement] is the abstract superclass for all DMN elements.
172///
173/// All DMN elements are contained within [Definitions] and that have a graphical
174/// representation in a DRD. This enumeration specifies the list
175/// of [DRGElements](DrgElement) contained in [Definitions].
176#[derive(Debug, Clone)]
177#[allow(clippy::large_enum_variant)]
178pub enum DrgElement {
179  Decision(Decision),
180  InputData(InputData),
181  BusinessKnowledgeModel(BusinessKnowledgeModel),
182  DecisionService(DecisionService),
183  KnowledgeSource(KnowledgeSource),
184}
185
186/// Enumeration of specific requirements.
187pub enum Requirement {
188  Information(InformationRequirement),
189  Knowledge(KnowledgeRequirement),
190  Authority(AuthorityRequirement),
191}
192
193/// [Definitions] element is the outermost containing object
194/// for all elements of a DMN decision model.
195/// It defines the scope of visibility and the namespace
196/// for all contained elements.
197#[named_element]
198#[dmn_element]
199#[derive(Debug, Clone)]
200pub struct Definitions {
201  /// This attribute identifies the expression language used in
202  /// [LiteralExpressions](LiteralExpression) within the scope
203  /// of this [Definitions]. The _Default_ is FEEL.
204  /// This value **MAY** be overridden on each individual [LiteralExpression].
205  /// The language **SHALL** be specified in a URI format.
206  pub(crate) expression_language: Option<Uri>,
207  /// This attribute identifies the type language used in
208  /// [LiteralExpressions](LiteralExpression) within the scope
209  /// of this [Definitions]. The _Default_ is FEEL.
210  /// This value **MAY** be overridden on each individual [ItemDefinition].
211  /// The language **SHALL** be specified in a URI format.
212  pub(crate) type_language: Option<Uri>,
213  /// Name of the tool used to export the XML serialization.
214  pub(crate) exporter: Option<String>,
215  /// Version of the tool used to export the XML serialization.
216  pub(crate) exporter_version: Option<String>,
217  /// Container for the instances of [ItemDefinition] that are contained in this [Definitions].
218  pub(crate) item_definitions: Vec<ItemDefinition>,
219  /// Container for the instances of [DrgElement] that are contained in this [Definitions].
220  pub(crate) drg_elements: Vec<DrgElement>,
221  /// Container for the instances of [BusinessContextElement] that are contained in this [Definitions].
222  pub(crate) business_context_elements: Vec<BusinessContextElementInstance>,
223  /// Container used to import externally defined elements and make them available
224  /// for use by elements in this [Definitions].
225  pub(crate) imports: Vec<Import>,
226  /// Optional diagram interchange information contained within this [Definitions].
227  pub(crate) dmndi: Option<Dmndi>,
228}
229
230impl Definitions {
231  /// Returns the reference to optional expression language used within the scope of this [Definitions].
232  pub fn expression_language(&self) -> &Option<String> {
233    &self.expression_language
234  }
235
236  /// Returns reference to the type language used within the scope of this [Definitions].
237  pub fn type_language(&self) -> &Option<String> {
238    &self.type_language
239  }
240
241  /// Returns reference to the name of the tool used to export the XML serialization.
242  pub fn exporter(&self) -> &Option<String> {
243    &self.exporter
244  }
245
246  /// Returns reference to the version of the tool used to export the XML serialization.
247  pub fn exporter_version(&self) -> &Option<String> {
248    &self.exporter_version
249  }
250
251  /// Returns reference to the container of instances of [ItemDefinition] contained in this [Definitions].
252  pub fn item_definitions(&self) -> &Vec<ItemDefinition> {
253    &self.item_definitions
254  }
255
256  /// Returns reference to the container of instances of [Import] contained in this [Definitions].
257  pub fn imports(&self) -> &Vec<Import> {
258    &self.imports
259  }
260
261  /// Returns reference to optional [Dmndi] container.
262  pub fn dmndi(&self) -> &Option<Dmndi> {
263    &self.dmndi
264  }
265
266  /// Returns reference to [DrgElements](DrgElement) container.
267  pub fn drg_elements(&self) -> Iter<DrgElement> {
268    self.drg_elements.iter()
269  }
270
271  /// Returns all decision definitions.
272  pub fn decisions(&self) -> Vec<Decision> {
273    self
274      .drg_elements
275      .iter()
276      .filter_map(|drg_element| {
277        if let DrgElement::Decision(decision) = drg_element {
278          Some(decision.clone())
279        } else {
280          None
281        }
282      })
283      .collect()
284  }
285
286  /// Returns all business knowledge model definitions.
287  pub fn business_knowledge_models(&self) -> Vec<BusinessKnowledgeModel> {
288    self
289      .drg_elements
290      .iter()
291      .filter_map(|drg_element| {
292        if let DrgElement::BusinessKnowledgeModel(bkm) = drg_element {
293          Some(bkm.clone())
294        } else {
295          None
296        }
297      })
298      .collect()
299  }
300
301  /// Returns all decision services definitions.
302  pub fn decision_services(&self) -> Vec<DecisionService> {
303    self
304      .drg_elements
305      .iter()
306      .filter_map(|drg_element| {
307        if let DrgElement::DecisionService(decision_service) = drg_element {
308          Some(decision_service.clone())
309        } else {
310          None
311        }
312      })
313      .collect()
314  }
315
316  /// Returns all knowledge source definitions.
317  pub fn knowledge_sources(&self) -> Vec<&KnowledgeSource> {
318    self
319      .drg_elements
320      .iter()
321      .filter_map(|drg_element| {
322        if let DrgElement::KnowledgeSource(knowledge_source) = drg_element {
323          Some(knowledge_source)
324        } else {
325          None
326        }
327      })
328      .collect()
329  }
330
331  /// Returns all input data definitions.
332  pub fn input_data(&self) -> Vec<InputData> {
333    self
334      .drg_elements
335      .iter()
336      .filter_map(|drg_element| {
337        if let DrgElement::InputData(input_data) = drg_element {
338          Some(input_data.clone())
339        } else {
340          None
341        }
342      })
343      .collect()
344  }
345
346  /// Returns performance indicators.
347  pub fn performance_indicators(&self) -> Vec<&PerformanceIndicator> {
348    self
349      .business_context_elements
350      .iter()
351      .filter_map(|item| match item {
352        BusinessContextElementInstance::PerformanceIndicator(performance_indicator) => Some(performance_indicator),
353        _ => None,
354      })
355      .collect()
356  }
357
358  /// Returns organisation units.
359  pub fn organisation_units(&self) -> Vec<&OrganizationUnit> {
360    self
361      .business_context_elements
362      .iter()
363      .filter_map(|item| match item {
364        BusinessContextElementInstance::OrganizationUnit(organisation_unit) => Some(organisation_unit),
365        _ => None,
366      })
367      .collect()
368  }
369
370  /// Returns decision with specified identifier.
371  pub fn get_decision(&self, id: &str) -> Option<&Decision> {
372    for drg_element in &self.drg_elements {
373      if let DrgElement::Decision(decision) = drg_element {
374        if decision.id() == id {
375          return Some(decision);
376        }
377      }
378    }
379    None
380  }
381
382  /// Returns input data with specified identifier.
383  pub fn get_input_data(&self, id: &str) -> Option<&InputData> {
384    for drg_element in &self.drg_elements {
385      if let DrgElement::InputData(input_data) = drg_element {
386        if input_data.id() == id {
387          return Some(input_data);
388        }
389      }
390    }
391    None
392  }
393
394  /// Returns business knowledge model with specified identifier.
395  pub fn get_business_knowledge_model(&self, id: &str) -> Option<&BusinessKnowledgeModel> {
396    for drg_element in &self.drg_elements {
397      if let DrgElement::BusinessKnowledgeModel(business_knowledge_model) = drg_element {
398        if business_knowledge_model.id() == id {
399          return Some(business_knowledge_model);
400        }
401      }
402    }
403    None
404  }
405
406  /// Returns knowledge source with specified identifier.
407  pub fn get_knowledge_source(&self, id: &str) -> Option<&KnowledgeSource> {
408    for drg_element in &self.drg_elements {
409      if let DrgElement::KnowledgeSource(knowledge_source) = drg_element {
410        if knowledge_source.id() == id {
411          return Some(knowledge_source);
412        }
413      }
414    }
415    None
416  }
417
418  /// Returns a requirement with specified identifier.
419  pub fn get_requirement(&self, id: &str) -> Option<Requirement> {
420    for drg_element in &self.drg_elements {
421      match drg_element {
422        DrgElement::Decision(decision) => {
423          for knowledge_requirement in &decision.knowledge_requirements {
424            if knowledge_requirement.id() == id {
425              return Some(Requirement::Knowledge(knowledge_requirement.clone()));
426            }
427          }
428          for information_requirement in &decision.information_requirements {
429            if information_requirement.id() == id {
430              return Some(Requirement::Information(information_requirement.clone()));
431            }
432          }
433          for authority_requirement in &decision.authority_requirements {
434            if authority_requirement.id() == id {
435              return Some(Requirement::Authority(authority_requirement.clone()));
436            }
437          }
438        }
439        DrgElement::BusinessKnowledgeModel(business_knowledge_model) => {
440          for knowledge_requirement in &business_knowledge_model.knowledge_requirements {
441            if knowledge_requirement.id() == id {
442              return Some(Requirement::Knowledge(knowledge_requirement.clone()));
443            }
444          }
445          for authority_requirement in &business_knowledge_model.authority_requirements {
446            if authority_requirement.id() == id {
447              return Some(Requirement::Authority(authority_requirement.clone()));
448            }
449          }
450        }
451        DrgElement::KnowledgeSource(knowledge_source) => {
452          for authority_requirement in &knowledge_source.authority_requirements {
453            if authority_requirement.id() == id {
454              return Some(Requirement::Authority(authority_requirement.clone()));
455            }
456          }
457        }
458        _ => {}
459      }
460    }
461    None
462  }
463}
464
465#[named_element]
466#[dmn_element]
467#[derive(Debug, Clone, PartialEq)]
468pub struct InformationItem {
469  /// Qualified name of the type of this [InformationItem].
470  pub(crate) type_ref: String,
471  /// Optional `FEEL` type of this [InformationItem].
472  pub(crate) feel_type: Option<FeelType>,
473}
474
475impl InformationItem {
476  /// Returns qualified name of the type of this [InformationItem].
477  pub fn type_ref(&self) -> &String {
478    &self.type_ref
479  }
480}
481
482impl FeelTypedElement for InformationItem {
483  /// Returns a reference to optional `FEEL` type of this element.
484  fn feel_type(&self) -> &Option<FeelType> {
485    &self.feel_type
486  }
487  /// Sets the `FEEL` type for this element.
488  fn set_feel_type(&mut self, feel_type: FeelType) {
489    self.feel_type = Some(feel_type);
490  }
491}
492
493/// [InputData] is used to model the inputs of a decision whose values
494/// are defined outside the decision model.
495#[named_element]
496#[dmn_element]
497#[derive(Debug, Clone)]
498pub struct InputData {
499  /// The instance of [InformationItem] that stores the result of this [InputData].
500  pub(crate) variable: InformationItem,
501}
502
503impl RequiredVariable for InputData {
504  /// Returns reference to a variable for this [BusinessKnowledgeModel].  
505  fn variable(&self) -> &InformationItem {
506    &self.variable
507  }
508}
509
510/// `Import` class is used when referencing external elements.
511///
512/// These elements can either be a DMN [DRGElement](DrgElement) or [ItemDefinition]
513/// instances contained in other [Definitions] elements, or non-DMN elements,
514/// such as an XML Schema or a PMML file.
515#[named_element]
516#[dmn_element]
517#[derive(Debug, Clone, PartialEq, Eq)]
518pub struct Import {
519  /// Specifies the style of import associated with this [Import].
520  pub(crate) import_type: String,
521  /// Identifies the location of the imported element.
522  pub(crate) location_uri: Option<String>,
523}
524
525impl Import {
526  /// Returns reference to the import type for this [Import].
527  pub fn import_type(&self) -> &str {
528    &self.import_type
529  }
530
531  /// Returns reference to the optional location URI for this [Import].
532  pub fn location_uri(&self) -> &Option<String> {
533    &self.location_uri
534  }
535
536  /// Returns reference to the namespace of this [Import].
537  pub fn namespace(&self) -> &str {
538    &self.namespace
539  }
540}
541
542/// An enumeration of concrete instances of abstract [Expression], which are:
543/// - [Conditional],
544/// - [Context],
545/// - [DecisionTable],
546/// - [Every],
547/// - [Filter],
548/// - [For],
549/// - [FunctionDefinition],
550/// - [Invocation],
551/// - [List],
552/// - [LiteralExpression],
553/// - [Relation],
554/// - [Some].
555#[derive(Debug, Clone, PartialEq)]
556pub enum ExpressionInstance {
557  Conditional(Box<Conditional>),
558  Context(Box<Context>),
559  DecisionTable(Box<DecisionTable>),
560  Every(Box<Every>),
561  Filter(Box<Filter>),
562  For(Box<For>),
563  FunctionDefinition(Box<FunctionDefinition>),
564  Invocation(Box<Invocation>),
565  List(Box<List>),
566  LiteralExpression(Box<LiteralExpression>),
567  Relation(Box<Relation>),
568  Some(Box<Some>),
569}
570
571/// A [Context] is composed of any number of model context entries, which are instances of [ContextEntry].
572#[dmn_element]
573#[expression]
574#[derive(Debug, Clone, PartialEq)]
575pub struct Context {
576  /// This attribute lists the instances of [ContextEntry] that compose this [Context].
577  pub(crate) context_entries: Vec<ContextEntry>,
578}
579
580impl Context {
581  /// Return a reference to context entries that compose this [Context].
582  pub fn context_entries(&self) -> &Vec<ContextEntry> {
583    &self.context_entries
584  }
585}
586
587/// The class [ContextEntry] is used to model `FEEL` context entries when a context is modeled as a [Context] element.
588#[derive(Debug, Clone, PartialEq)]
589pub struct ContextEntry {
590  /// The instance of [InformationItem] that is contained in this [ContextEntry],
591  /// and whose name is the key in the modeled context entry.
592  pub variable: Option<InformationItem>,
593  /// The instance of [Expression] that is the expression in this [ContextEntry].
594  pub value: ExpressionInstance,
595}
596
597/// [LiteralExpression] is used to model a value expression whose value
598/// is specified by text in some specified expression language.
599#[dmn_element]
600#[expression]
601#[derive(Debug, Clone, PartialEq, Eq)]
602pub struct LiteralExpression {
603  /// The text of this [LiteralExpression].
604  /// It SHALL be a valid expression in the `expression_language`.
605  pub(crate) text: Option<String>,
606  /// Identifies the expression language used in this [LiteralExpression].
607  pub(crate) expression_language: Option<String>,
608  /// The instance of [ImportedValue](Import) that specifies
609  /// where the text of this [LiteralExpression] is located.
610  pub(crate) imported_values: Option<Import>,
611}
612
613impl LiteralExpression {
614  pub fn text(&self) -> &Option<String> {
615    &self.text
616  }
617
618  pub fn expression_language(&self) -> Option<String> {
619    self.expression_language.clone()
620  }
621
622  pub fn imported_values(&self) -> Option<Import> {
623    self.imported_values.clone()
624  }
625}
626
627/// [Invocation] is a mechanism for the evaluation of value expressions.
628///
629/// [Invocation] is a mechanism that permits the evaluation of one value expression
630/// – the invoked expression – inside another value expression
631/// – the invoking expression – by binding locally the input variables of the invoked
632/// expression to values inside the invoking expression.
633#[dmn_element]
634#[expression]
635#[derive(Debug, Clone, PartialEq)]
636pub struct Invocation {
637  /// An expression whose value is a function.
638  pub(crate) called_function: ExpressionInstance,
639  /// Instances of [Binding] used to bind the formal parameters of the called function in this [Invocation].
640  pub(crate) bindings: Vec<Binding>,
641}
642
643impl Invocation {
644  /// Returns a reference to called function which is an instance of [Expression].
645  pub fn called_function(&self) -> &ExpressionInstance {
646    &self.called_function
647  }
648  /// Returns a reference to the collection of binding instances.
649  pub fn bindings(&self) -> &Vec<Binding> {
650    &self.bindings
651  }
652}
653
654#[derive(Debug, Clone, PartialEq)]
655pub struct Binding {
656  /// The [InformationItem] on which the `calledFunction` of the owning
657  /// instance of [Invocation] depends that is bound by this [Binding].
658  pub(crate) parameter: InformationItem,
659  /// The instance of [Expression] to which the parameter in this [Binding] is
660  /// bound when the owning instance of [Invocation] is evaluated.
661  pub(crate) binding_formula: Option<ExpressionInstance>,
662}
663
664impl Binding {
665  /// Returns a reference to parameter.
666  pub fn parameter(&self) -> &InformationItem {
667    &self.parameter
668  }
669  /// Returns a reference to binding formula.
670  pub fn binding_formula(&self) -> &Option<ExpressionInstance> {
671    &self.binding_formula
672  }
673}
674
675/// [Decision]
676#[named_element]
677#[dmn_element]
678#[derive(Debug, Clone)]
679pub struct Decision {
680  /// A natural language question that characterizes the [Decision],
681  /// such that the output of the [Decision] is an answer to the question.
682  pub(crate) question: Option<String>,
683  /// A natural language description of the answers allowed for the question
684  /// such as `Yes/No`, a list of allowed values, a range of numeric values etc.
685  pub(crate) allowed_answers: Option<String>,
686  /// The instance of [InformationItem] that stores the result of this [Decision].
687  pub(crate) variable: InformationItem,
688  /// The instance of the [Expression] for the [Decision].
689  pub(crate) decision_logic: Option<ExpressionInstance>,
690  /// Collection of the instances of [InformationRequirement] that compose this [Decision].
691  pub(crate) information_requirements: Vec<InformationRequirement>,
692  /// Collection of the instances of [KnowledgeRequirement] that compose this [Decision].
693  pub(crate) knowledge_requirements: Vec<KnowledgeRequirement>,
694  /// Collection of the instances of [AuthorityRequirement] that compose this [Decision].
695  pub(crate) authority_requirements: Vec<AuthorityRequirement>,
696  //TODO add the following:
697  //  supported_objectives
698  //  impacted_performance_indicator
699  //  decision_maker
700  //  decision_owner
701  //  using_processes
702  //  using_tasks
703}
704
705impl Decision {
706  /// Returns a reference to a natural language question that characterizes the [Decision].
707  pub fn question(&self) -> &Option<String> {
708    &self.question
709  }
710  /// Returns a reference to a natural language description of the answers allowed for the question defined in this [Decision].
711  pub fn allowed_answers(&self) -> &Option<String> {
712    &self.allowed_answers
713  }
714  /// Return a reference to a variable that stores the result of this [Decision].
715  pub fn variable(&self) -> &InformationItem {
716    &self.variable
717  }
718  /// Returns a reference to optional [Expression].
719  pub fn decision_logic(&self) -> &Option<ExpressionInstance> {
720    &self.decision_logic
721  }
722  /// Returns a reference to collection of [InformationRequirement].
723  pub fn information_requirements(&self) -> &Vec<InformationRequirement> {
724    &self.information_requirements
725  }
726  /// Returns a reference to collection of [KnowledgeRequirement].
727  pub fn knowledge_requirements(&self) -> &Vec<KnowledgeRequirement> {
728    &self.knowledge_requirements
729  }
730  /// Returns a reference to collection of [AuthorityRequirement].
731  pub fn authority_requirements(&self) -> &Vec<AuthorityRequirement> {
732    &self.authority_requirements
733  }
734}
735
736/// The class [InformationRequirement] is used to model an information requirement,
737/// as represented by a plain arrow in a DRD.
738#[dmn_element]
739#[derive(Debug, Clone)]
740pub struct InformationRequirement {
741  /// Reference to [Decision] that this [InformationRequirement] associates
742  /// with its containing  [Decision] element.
743  pub(crate) required_decision: Option<HRef>,
744  /// Reference to [InputData] that this [InformationRequirement] associates
745  /// with its containing [Decision] element.
746  pub(crate) required_input: Option<HRef>,
747}
748
749impl InformationRequirement {
750  /// Returns reference to optional URI pointing a [Decision].
751  pub fn required_decision(&self) -> &Option<HRef> {
752    &self.required_decision
753  }
754
755  /// Returns reference to optional URI pointing an [InputData].
756  pub fn required_input(&self) -> &Option<HRef> {
757    &self.required_input
758  }
759}
760
761/// The class [KnowledgeRequirement] is used to model a knowledge requirement,
762/// as represented by a dashed arrow in a DRD.
763#[dmn_element]
764#[derive(Debug, Clone)]
765pub struct KnowledgeRequirement {
766  /// Reference to [Invocable] that this [KnowledgeRequirement] associates with
767  /// its containing [Decision] or [BusinessKnowledgeModel] element.
768  pub(crate) required_knowledge: HRef,
769}
770
771impl KnowledgeRequirement {
772  /// Returns a reference to the [Invocable].
773  pub fn required_knowledge(&self) -> &HRef {
774    &self.required_knowledge
775  }
776}
777
778/// The class [AuthorityRequirement] is used to model an authority requirement,
779/// as represented by an arrow drawn with a dashed line and a filled circular head in a DRD
780#[dmn_element]
781#[derive(Debug, Clone)]
782pub struct AuthorityRequirement {
783  /// The instance of [KnowledgeSource] that this [AuthorityRequirement] associates
784  /// with its containing [KnowledgeSource], [Decision] or [BusinessKnowledgeModel] element.
785  pub(crate) required_authority: Option<HRef>,
786  /// The instance of [Decision] that this [AuthorityRequirement] associates
787  /// with its containing [KnowledgeSource] element.
788  pub(crate) required_decision: Option<HRef>,
789  /// The instance of [InputData] that this [AuthorityRequirement] associates
790  /// with its containing [KnowledgeSource] element.
791  pub(crate) required_input: Option<HRef>,
792}
793
794impl AuthorityRequirement {
795  /// Returns reference to optional [KnowledgeSource].
796  pub fn required_authority(&self) -> &Option<HRef> {
797    &self.required_authority
798  }
799  /// Returns reference to optional [Decision].
800  pub fn required_decision(&self) -> &Option<HRef> {
801    &self.required_decision
802  }
803  /// Returns reference to optional [InputData].
804  pub fn required_input(&self) -> &Option<HRef> {
805    &self.required_input
806  }
807}
808
809/// The class [KnowledgeSource] is used to model authoritative knowledge sources in a decision model.
810/// In a DRD, an instance of [KnowledgeSource] is represented by a `knowledge source` diagram element.
811#[named_element]
812#[dmn_element]
813#[derive(Debug, Clone)]
814pub struct KnowledgeSource {
815  /// Collection of the instances of [AuthorityRequirement] that compose this [Decision].
816  pub(crate) authority_requirements: Vec<AuthorityRequirement>,
817}
818
819impl KnowledgeSource {
820  /// Returns a reference to collection of [AuthorityRequirement].
821  pub fn authority_requirements(&self) -> &Vec<AuthorityRequirement> {
822    &self.authority_requirements
823  }
824}
825
826/// A business knowledge model.
827///
828/// A business knowledge model has an abstract part, representing reusable,
829/// invocable decision logic, and a concrete part, which mandates that the decision logic
830/// must be a single FEEL boxed function definition.
831#[named_element]
832#[dmn_element]
833#[derive(Debug, Clone)]
834pub struct BusinessKnowledgeModel {
835  /// Variable that is bound to the function defined by the [FunctionDefinition] for this [BusinessKnowledgeModel].
836  pub(crate) variable: InformationItem,
837  /// The function that encapsulates the logic encapsulated by this [BusinessKnowledgeModel].
838  pub(crate) encapsulated_logic: Option<FunctionDefinition>,
839  /// This attribute lists the instances of [KnowledgeRequirement] that compose this [BusinessKnowledgeModel].
840  pub(crate) knowledge_requirements: Vec<KnowledgeRequirement>,
841  /// This attribute lists the instances of [AuthorityRequirement] that compose this [BusinessKnowledgeModel].
842  pub(crate) authority_requirements: Vec<AuthorityRequirement>,
843}
844
845impl BusinessKnowledgeModel {
846  /// Returns reference to a variable for this [BusinessKnowledgeModel].
847  pub fn encapsulated_logic(&self) -> &Option<FunctionDefinition> {
848    &self.encapsulated_logic
849  }
850  /// Returns reference to the collection of instances of [KnowledgeRequirement] that compose this [BusinessKnowledgeModel].
851  pub fn knowledge_requirements(&self) -> &Vec<KnowledgeRequirement> {
852    &self.knowledge_requirements
853  }
854  /// Returns reference to the collection of instances of [AuthorityRequirement] that compose this [BusinessKnowledgeModel].
855  pub fn authority_requirements(&self) -> &Vec<AuthorityRequirement> {
856    &self.authority_requirements
857  }
858}
859
860impl RequiredVariable for BusinessKnowledgeModel {
861  /// Returns reference to a variable for this [BusinessKnowledgeModel].
862  fn variable(&self) -> &InformationItem {
863    &self.variable
864  }
865}
866
867/// The [DecisionService] class is used to define named decision services
868/// against the decision model contained in an instance of [Definitions].
869#[named_element]
870#[dmn_element]
871#[derive(Debug, Clone)]
872pub struct DecisionService {
873  /// Variable for this [DecisionService].
874  pub(crate) variable: InformationItem,
875  /// Collection of references to the instances of [Decision] required to be output by this [DecisionService].
876  pub(crate) output_decisions: Vec<HRef>,
877  /// Collection of references to the instances of [Decision] to be encapsulated in this [DecisionService].
878  pub(crate) encapsulated_decisions: Vec<HRef>,
879  /// Collection of references to the instances of [Decision] required as input by this [DecisionService].
880  pub(crate) input_decisions: Vec<HRef>,
881  /// Collection of references to the instances of [InputData] required as input by this [DecisionService].
882  pub(crate) input_data: Vec<HRef>,
883}
884
885impl DecisionService {
886  /// Returns a reference to collection of references to input [Decision]s for this [DecisionService].
887  pub fn input_decisions(&self) -> &Vec<HRef> {
888    &self.input_decisions
889  }
890  /// Returns a reference to collection of references to encapsulated [Decision]s for this [DecisionService].
891  pub fn encapsulated_decisions(&self) -> &Vec<HRef> {
892    &self.encapsulated_decisions
893  }
894  /// Returns a reference to collection of references to output [Decision]s for this [DecisionService].
895  pub fn output_decisions(&self) -> &Vec<HRef> {
896    &self.output_decisions
897  }
898  /// Returns a reference to collection of references to [InputData] for this [DecisionService].
899  pub fn input_data(&self) -> &Vec<HRef> {
900    &self.input_data
901  }
902}
903
904impl RequiredVariable for DecisionService {
905  /// Returns reference to a variable for this [DecisionService].
906  fn variable(&self) -> &InformationItem {
907    &self.variable
908  }
909}
910
911/// Item definition types.
912#[derive(Debug, Clone, PartialEq)]
913pub enum ItemDefinitionType {
914  SimpleType(FeelType),
915  ReferencedType(String, String),
916  ComponentType,
917  CollectionOfSimpleType(FeelType),
918  CollectionOfReferencedType(String, String),
919  CollectionOfComponentType,
920  FunctionType,
921}
922
923/// [ItemDefinition] is used to model the inputs of a decision,
924/// whose values are defined outside the decision model.
925#[named_element]
926#[dmn_element]
927#[expression]
928#[derive(Debug, Clone)]
929pub struct ItemDefinition {
930  /// This attribute identifies the type language used to specify the base
931  /// type of this [ItemDefinition]. This value overrides the type
932  /// language specified in the [Definitions] element. The default is `FEEL`.
933  /// The language `SHALL` be specified in URI format.
934  pub(crate) type_language: Option<String>,
935  /// This attribute contains `FEEL` built-in type only when the `type_language` attribute
936  /// is `FEEL` and the `type_ref` attribute defines one of the built-in `FEEL` types.
937  pub(crate) feel_type: Option<FeelType>,
938  /// Possible values or ranges of values in the base type that are allowed in this [ItemDefinition].
939  pub(crate) allowed_values: Option<UnaryTests>,
940  /// Defines zero or more nested [ItemDefinitions](ItemDefinition) that compose this [ItemDefinition].
941  pub(crate) item_components: Vec<ItemDefinition>,
942  /// Setting this flag to true indicates that the actual values defined by
943  /// this [ItemDefinition] are collections of allowed values.
944  /// The default value is [false].
945  pub(crate) is_collection: bool,
946  /// Describes an optional [FunctionItem] that compose this [ItemDefinition].
947  pub(crate) function_item: Option<FunctionItem>,
948}
949
950impl ItemDefinition {
951  /// Returns reference to the type language used within the scope of this [ItemDefinition].
952  pub fn type_language(&self) -> &Option<String> {
953    &self.type_language
954  }
955  /// Returns reference to possible values or ranges of values
956  /// in the base type that are allowed in this [ItemDefinition].
957  pub fn allowed_values(&self) -> &Option<UnaryTests> {
958    &self.allowed_values
959  }
960  /// Returns reference to nested [ItemDefinitions](ItemDefinition) that compose this [ItemDefinition].
961  pub fn item_components(&self) -> &Vec<ItemDefinition> {
962    &self.item_components
963  }
964  /// Returns mutable reference to nested [ItemDefinitions](ItemDefinition) that compose this [ItemDefinition].
965  pub fn item_components_mut(&mut self) -> &mut Vec<ItemDefinition> {
966    &mut self.item_components
967  }
968  /// Returns flag indicating if the actual values are collections of allowed values.
969  pub fn is_collection(&self) -> bool {
970    self.is_collection
971  }
972  /// Returns a reference to optional `FEEL` type.
973  pub fn feel_type(&self) -> &Option<FeelType> {
974    &self.feel_type
975  }
976  /// Sets the `FEEL` type for this element.
977  pub fn set_feel_type(&mut self, feel_type: FeelType) {
978    self.feel_type = Some(feel_type);
979  }
980  /// Returns a reference to an optional [FunctionItem] that compose this [ItemDefinition].
981  pub fn function_item(&self) -> &Option<FunctionItem> {
982    &self.function_item
983  }
984}
985
986/// [UnaryTests] is used to model a boolean test, where the argument
987/// to be tested is implicit or denoted with a **?**.
988/// Test is specified by text in some specified expression language.
989#[derive(Debug, Clone)]
990pub struct UnaryTests {
991  /// The text of this [UnaryTests].
992  /// It SHALL be a valid expression in the expressionLanguage.
993  pub(crate) text: Option<String>,
994  /// This attribute identifies the expression language used in this [UnaryTests].
995  /// This value overrides the expression language specified for the containing
996  /// instance of DecisionRequirementDiagram.
997  /// The language SHALL be specified in a URI format.
998  pub(crate) expression_language: Option<String>,
999}
1000
1001impl UnaryTests {
1002  /// Returns reference to optional text of this [UnaryTests].
1003  pub fn text(&self) -> &Option<String> {
1004    &self.text
1005  }
1006  /// Returns reference to optional expression language used in this [UnaryTests].
1007  pub fn expression_language(&self) -> &Option<String> {
1008    &self.expression_language
1009  }
1010}
1011
1012/// [FunctionItem] defines the signature of a function:
1013/// the parameters and the output type of the function.
1014#[derive(Debug, Clone)]
1015pub struct FunctionItem {
1016  /// Reference to output type of the function.
1017  pub(crate) output_type_ref: Option<String>,
1018  /// Function parameters as [InformationItems](InformationItem).
1019  pub(crate) parameters: Vec<InformationItem>,
1020}
1021
1022impl FunctionItem {
1023  /// Returns reference to output type of function.
1024  pub fn output_type_ref(&self) -> &Option<String> {
1025    &self.output_type_ref
1026  }
1027  /// Returns reference to function parameters defined
1028  /// as collection of [InformationItems](InformationItem).
1029  pub fn parameters(&self) -> &Vec<InformationItem> {
1030    &self.parameters
1031  }
1032}
1033
1034/// Defines the type of the [FunctionDefinition].
1035/// The default value is `FEEL`. Supported values also include `Java` and `PMML`.
1036#[derive(Debug, Clone, PartialEq, Eq)]
1037pub enum FunctionKind {
1038  Feel,
1039  Java,
1040  Pmml,
1041}
1042
1043/// [FunctionItem] defines the signature of a function:
1044/// the parameters and the output type of the function.
1045#[dmn_element]
1046#[expression]
1047#[derive(Debug, Clone, PartialEq)]
1048pub struct FunctionDefinition {
1049  /// Container for instances of [InformationItem] that are the parameters of this [FunctionDefinition].
1050  pub(crate) formal_parameters: Vec<InformationItem>,
1051  /// The instance of [Expression] that is the body in this [FunctionDefinition].
1052  pub(crate) body: Option<ExpressionInstance>,
1053  /// Type of this [FunctionDefinition], the default value is FEEL.
1054  pub(crate) kind: FunctionKind,
1055}
1056
1057impl FunctionDefinition {
1058  /// Returns reference to container of [InformationItem] of this [FunctionDefinition].
1059  pub fn formal_parameters(&self) -> &Vec<InformationItem> {
1060    &self.formal_parameters
1061  }
1062  /// Returns reference to [Expression] that is the body in this [FunctionDefinition].
1063  pub fn body(&self) -> &Option<ExpressionInstance> {
1064    &self.body
1065  }
1066  /// Returns the type of this [FunctionDefinition].
1067  pub fn kind(&self) -> &FunctionKind {
1068    &self.kind
1069  }
1070}
1071
1072/// A [Relation] is convenient a shorthand for a list of similar contexts.
1073///
1074/// A [Relation] has a column instead of repeated `ContextEntry`s,
1075/// and a `List` is used for every row, with one of the `List`’s
1076/// expression for each column value.
1077#[dmn_element]
1078#[expression]
1079#[derive(Debug, Clone, PartialEq)]
1080pub struct Relation {
1081  /// This attribute lists the instances of [List] that are the rows in this [Relation].
1082  pub(crate) rows: Vec<List>,
1083  /// This attributes lists the instances of [InformationItem] that define the columns in this [Relation].
1084  pub(crate) columns: Vec<InformationItem>,
1085}
1086
1087impl Relation {
1088  /// Returns a reference to collection of relation's rows.
1089  pub fn rows(&self) -> &Vec<List> {
1090    &self.rows
1091  }
1092  /// Returns a reference to collection of relation's columns.
1093  pub fn columns(&self) -> &Vec<InformationItem> {
1094    &self.columns
1095  }
1096}
1097
1098/// A [List] is simply a list of elements, which are instances of [Expression]s.
1099#[dmn_element]
1100#[expression]
1101#[derive(Debug, Clone, PartialEq)]
1102pub struct List {
1103  /// This attribute lists the instances of [Expression] that are the elements of this [List].
1104  pub(crate) elements: Vec<ExpressionInstance>,
1105}
1106
1107impl List {
1108  /// Returns a reference to collection of list's elements.
1109  pub fn elements(&self) -> &Vec<ExpressionInstance> {
1110    &self.elements
1111  }
1112}
1113
1114/// A [Conditional] is a representation of a visual way to express an if statement.
1115#[dmn_element]
1116#[expression]
1117#[derive(Debug, Clone, PartialEq)]
1118pub struct Conditional {
1119  /// This attribute holds the expression that is evaluated by the conditional expression.
1120  pub(crate) if_expression: ChildExpression,
1121  /// This attribute holds the expression that will be evaluated when the condition in the if statement evaluates to `true`.
1122  pub(crate) then_expression: ChildExpression,
1123  /// This attribute holds the expression that will be evaluated when the condition in the if statement evaluates to `false`.
1124  pub(crate) else_expression: ChildExpression,
1125}
1126
1127impl Conditional {
1128  pub fn if_expression(&self) -> &ChildExpression {
1129    &self.if_expression
1130  }
1131
1132  pub fn then_expression(&self) -> &ChildExpression {
1133    &self.then_expression
1134  }
1135
1136  pub fn else_expression(&self) -> &ChildExpression {
1137    &self.else_expression
1138  }
1139}
1140
1141/// A [Filter] is a visual way to express list filtering.
1142#[dmn_element]
1143#[expression]
1144#[derive(Debug, Clone, PartialEq)]
1145pub struct Filter {
1146  /// This attribute holds the expression that is evaluated as the collection to be filtered.
1147  pub(crate) in_expression: ChildExpression,
1148  /// This attribute holds the expression that is used to filter the collection.
1149  pub(crate) match_expression: ChildExpression,
1150}
1151
1152impl Filter {
1153  pub fn in_expression(&self) -> &ChildExpression {
1154    &self.in_expression
1155  }
1156
1157  pub fn match_expression(&self) -> &ChildExpression {
1158    &self.match_expression
1159  }
1160}
1161
1162/// A [For] is a visual representation of a loop.
1163#[dmn_element]
1164#[expression]
1165#[derive(Debug, Clone, PartialEq)]
1166pub struct For {
1167  /// This attribute holds name of the iterator variable that will be populated at each iteration.
1168  pub(crate) iterator_variable: String,
1169  /// This attribute holds the expression that is evaluated as the collection to be processed.
1170  pub(crate) in_expression: TypedChildExpression,
1171  /// This attribute holds the expression that is evaluated to create the new collection that will be returned.
1172  pub(crate) return_expression: ChildExpression,
1173}
1174
1175impl For {
1176  pub fn iterator_variable(&self) -> &String {
1177    &self.iterator_variable
1178  }
1179
1180  pub fn in_expression(&self) -> &TypedChildExpression {
1181    &self.in_expression
1182  }
1183
1184  pub fn return_expression(&self) -> &ChildExpression {
1185    &self.return_expression
1186  }
1187}
1188
1189/// A [Every] is a visual representation of an expression where all
1190/// `satisfies` needs to be true for it to return true.
1191#[dmn_element]
1192#[expression]
1193#[derive(Debug, Clone, PartialEq)]
1194pub struct Every {
1195  /// This attribute holds name of the iterator variable that will be populated at each iteration.
1196  pub(crate) iterator_variable: String,
1197  /// This attribute holds the expression that is evaluated as the collection to be processed.
1198  pub(crate) in_expression: TypedChildExpression,
1199  /// This attribute holds the expression that is evaluated to determine if the current item satisfies a condition.
1200  pub(crate) satisfies_expression: ChildExpression,
1201}
1202
1203impl Every {
1204  pub fn iterator_variable(&self) -> &String {
1205    &self.iterator_variable
1206  }
1207
1208  pub fn in_expression(&self) -> &TypedChildExpression {
1209    &self.in_expression
1210  }
1211
1212  pub fn satisfies_expression(&self) -> &ChildExpression {
1213    &self.satisfies_expression
1214  }
1215}
1216
1217/// A [Some] is a visual representation of an expression where at least one of the
1218/// `satisfies` needs to be true for it to return true.
1219#[dmn_element]
1220#[expression]
1221#[derive(Debug, Clone, PartialEq)]
1222pub struct Some {
1223  /// This attribute holds name of the iterator variable that will be populated at each iteration.
1224  pub(crate) iterator_variable: String,
1225  /// This attribute holds the expression that is evaluated as the collection to be processed.
1226  pub(crate) in_expression: TypedChildExpression,
1227  /// This attribute holds the expression that is evaluated to determine if the current item satisfies a condition.
1228  pub(crate) satisfies_expression: ChildExpression,
1229}
1230
1231impl Some {
1232  pub fn iterator_variable(&self) -> &String {
1233    &self.iterator_variable
1234  }
1235
1236  pub fn in_expression(&self) -> &TypedChildExpression {
1237    &self.in_expression
1238  }
1239
1240  pub fn satisfies_expression(&self) -> &ChildExpression {
1241    &self.satisfies_expression
1242  }
1243}
1244
1245#[derive(Debug, Clone, PartialEq)]
1246pub struct ChildExpression {
1247  /// Optional identifier of this [ChildExpression].
1248  pub(crate) id: DmnId,
1249  /// The instance of [Expression] trait that is the expression in this [ChildExpression].
1250  pub(crate) value: ExpressionInstance,
1251}
1252
1253impl ChildExpression {
1254  pub fn id(&self) -> &DmnId {
1255    &self.id
1256  }
1257
1258  pub fn value(&self) -> &ExpressionInstance {
1259    &self.value
1260  }
1261}
1262
1263#[expression]
1264#[derive(Debug, Clone, PartialEq)]
1265pub struct TypedChildExpression {
1266  /// Optional identifier of this [TypedChildExpression].
1267  pub(crate) id: DmnId,
1268  /// The instance of [Expression] trait that is the expression in this [TypedChildExpression].
1269  pub(crate) value: ExpressionInstance,
1270}
1271
1272impl TypedChildExpression {
1273  pub fn id(&self) -> &DmnId {
1274    &self.id
1275  }
1276
1277  pub fn value(&self) -> &ExpressionInstance {
1278    &self.value
1279  }
1280}
1281
1282/// Decision table.
1283#[dmn_element]
1284#[expression]
1285#[derive(Debug, Clone, PartialEq, Eq)]
1286pub struct DecisionTable {
1287  /// Information item name, for which the decision table is its value expression.
1288  /// This is usually the name of the decision or the name of business knowledge model for
1289  /// which the decision table provides the decision logic.
1290  pub(crate) information_item_name: Option<String>,
1291  /// List of instances of input clause that compose this decision table.
1292  pub(crate) input_clauses: Vec<InputClause>,
1293  /// List of instances of output clause that compose this decision table.
1294  pub(crate) output_clauses: Vec<OutputClause>,
1295  /// List of instances of rule annotation clause that compose this decision table.
1296  pub(crate) annotations: Vec<RuleAnnotationClause>,
1297  /// List of instances of decision rule that compose this decision table.
1298  pub(crate) rules: Vec<DecisionRule>,
1299  /// Hit policy associated with the instance of the decision table.
1300  pub(crate) hit_policy: HitPolicy,
1301  /// Optional aggregation type when the hit policy is `COLLECT`.
1302  pub(crate) aggregation: Option<BuiltinAggregator>,
1303  /// Preferred representation of the instance of the decision table.
1304  pub(crate) preferred_orientation: DecisionTableOrientation,
1305  /// Optional output label for the description of the decision table output,
1306  /// may be the same as the name of the information item for which the
1307  /// decision table is the value expression.
1308  pub(crate) output_label: Option<String>,
1309}
1310
1311impl Display for DecisionTable {
1312  /// Implements [Display] trait for [DecisionTable].
1313  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1314    let mut buffer = String::new();
1315    buffer.push_str("Decision table:\n");
1316    buffer.push_str(format!(">> preferred orientation: {}\n", self.preferred_orientation).as_str());
1317    buffer.push_str(">> information item name: ");
1318    if let Some(text) = &self.information_item_name {
1319      buffer.push_str(format!("\n'{text}'\n").as_str());
1320    } else {
1321      buffer.push_str("none\n");
1322    }
1323    buffer.push_str(format!(">> hit policy: {}\n", self.hit_policy).as_str());
1324    buffer.push_str(">> aggregation: ");
1325    if let Some(aggregation) = &self.aggregation {
1326      buffer.push_str(format!("{aggregation}\n").as_str());
1327    } else {
1328      buffer.push_str("none\n");
1329    }
1330    buffer.push_str(">> output label: ");
1331    if let Some(text) = &self.output_label {
1332      buffer.push_str(format!("\n'{text}'\n").as_str());
1333    } else {
1334      buffer.push_str("none\n");
1335    }
1336    write!(f, "{buffer}")
1337  }
1338}
1339
1340impl DecisionTable {
1341  /// Creates a new decision table.
1342  #[allow(clippy::too_many_arguments)]
1343  pub fn new(
1344    information_item_name: Option<String>,
1345    input_clauses: Vec<InputClause>,
1346    output_clauses: Vec<OutputClause>,
1347    annotations: Vec<RuleAnnotationClause>,
1348    rules: Vec<DecisionRule>,
1349    hit_policy: HitPolicy,
1350    aggregation: Option<BuiltinAggregator>,
1351    preferred_orientation: DecisionTableOrientation,
1352    output_label: Option<String>,
1353  ) -> Self {
1354    Self {
1355      namespace: "".to_string(),
1356      model_name: "".to_string(),
1357      id: DmnId::Generated(gen_id()),
1358      description: None,
1359      label: None,
1360      extension_elements: vec![],
1361      extension_attributes: vec![],
1362      type_ref: None,
1363      information_item_name,
1364      input_clauses,
1365      output_clauses,
1366      annotations,
1367      rules,
1368      hit_policy,
1369      aggregation,
1370      preferred_orientation,
1371      output_label,
1372    }
1373  }
1374
1375  /// Returns the information item name.
1376  pub fn information_item_name(&self) -> &Option<String> {
1377    &self.information_item_name
1378  }
1379
1380  /// Returns an iterator over input clauses.
1381  pub fn input_clauses(&self) -> Iter<InputClause> {
1382    self.input_clauses.iter()
1383  }
1384
1385  /// Returns an iterator over output clauses.
1386  pub fn output_clauses(&self) -> Iter<OutputClause> {
1387    self.output_clauses.iter()
1388  }
1389
1390  /// Returns an iterator over annotations.
1391  pub fn annotations(&self) -> Iter<RuleAnnotationClause> {
1392    self.annotations.iter()
1393  }
1394
1395  /// Returns an iterator over the rules.
1396  pub fn rules(&self) -> Iter<DecisionRule> {
1397    self.rules.iter()
1398  }
1399
1400  /// Returns the [HitPolicy] of this decision table.
1401  pub fn hit_policy(&self) -> HitPolicy {
1402    self.hit_policy
1403  }
1404
1405  /// Returns the aggregation when the [HitPolicy] is `COLLECT`.
1406  pub fn aggregation(&self) -> &Option<BuiltinAggregator> {
1407    &self.aggregation
1408  }
1409
1410  /// Returns preferred orientation for this decision table.
1411  pub fn preferred_orientation(&self) -> &DecisionTableOrientation {
1412    &self.preferred_orientation
1413  }
1414
1415  /// Return an output label.
1416  pub fn output_label(&self) -> &Option<String> {
1417    &self.output_label
1418  }
1419
1420  /// Returns `true` when allowed input and/or allowed output values are present in decision table.
1421  pub fn allowed_values_present(&self) -> bool {
1422    for input_clause in &self.input_clauses {
1423      if input_clause.allowed_input_values.is_some() {
1424        return true;
1425      }
1426    }
1427    for output_clause in &self.output_clauses {
1428      if output_clause.allowed_output_values.is_some() {
1429        return true;
1430      }
1431    }
1432    false
1433  }
1434}
1435
1436/// Orientation of the decision table.
1437#[derive(Debug, Clone, PartialEq, Eq)]
1438pub enum DecisionTableOrientation {
1439  /// Decision table is presented horizontally, rules are presented as rows.
1440  RuleAsRow,
1441  /// Decision table is presented vertically, rules are presented as columns.
1442  RuleAsColumn,
1443  /// Decision table is presented as crosstab, rules are composed of two input dimensions.
1444  CrossTable,
1445}
1446
1447impl Display for DecisionTableOrientation {
1448  /// Implements [Display] trait for [DecisionTableOrientation].
1449  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1450    match self {
1451      DecisionTableOrientation::RuleAsRow => write!(f, "Rule-as-Row"),
1452      DecisionTableOrientation::RuleAsColumn => write!(f, "Rule-as-Column"),
1453      DecisionTableOrientation::CrossTable => write!(f, "CrossTable"),
1454    }
1455  }
1456}
1457
1458impl TryFrom<&str> for DecisionTableOrientation {
1459  type Error = DsntkError;
1460  /// Tries to construct a decision table orientation from its text representation.
1461  fn try_from(value: &str) -> Result<Self, Self::Error> {
1462    match value.trim() {
1463      "Rule-as-Row" => Ok(DecisionTableOrientation::RuleAsRow),
1464      "Rule-as-Column" => Ok(DecisionTableOrientation::RuleAsColumn),
1465      "CrossTable" => Ok(DecisionTableOrientation::CrossTable),
1466      other => Err(err_invalid_decision_table_orientation(other)),
1467    }
1468  }
1469}
1470
1471/// Hit policy.
1472#[derive(Debug, PartialEq, Eq, Copy, Clone)]
1473pub enum HitPolicy {
1474  /// `UNIQUE` hit policy. No overlapping rules are allowed, only single rule can be matched.
1475  /// This is the default value for hit policy. Crosstab decision tables may have only unique hit policy.
1476  Unique,
1477  /// `ANY` hit policy. Rules may overlap, but all matching rules show equal output entries.
1478  /// If matching rules have non-equal output entries, this policy is incorrect and the result is undefined.
1479  Any,
1480  /// `PRIORITY` hit policy. Multiple rules can match, with different output entries for each output.
1481  /// This policy returns matching rule with the highest priority. Output priorities are specified
1482  /// in the ordered list of output values, in decreasing order of priority.
1483  Priority,
1484  /// `FIRST` hit policy...
1485  First,
1486  /// `COLLECT` hit policy...
1487  Collect(BuiltinAggregator),
1488  /// `OUTPUT ORDER` hit policy...
1489  OutputOrder,
1490  /// `RULE ORDER` hit policy...
1491  RuleOrder,
1492}
1493
1494impl Display for HitPolicy {
1495  /// Implements [Display] trait for [HitPolicy].
1496  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1497    match self {
1498      HitPolicy::Unique => write!(f, "U"),
1499      HitPolicy::Any => write!(f, "A"),
1500      HitPolicy::Priority => write!(f, "P"),
1501      HitPolicy::First => write!(f, "F"),
1502      HitPolicy::Collect(aggregator) => write!(f, "{aggregator}"),
1503      HitPolicy::OutputOrder => write!(f, "O"),
1504      HitPolicy::RuleOrder => write!(f, "R"),
1505    }
1506  }
1507}
1508
1509impl TryFrom<&str> for HitPolicy {
1510  type Error = DsntkError;
1511  /// Creates a hit policy from text.
1512  fn try_from(value: &str) -> Result<Self, Self::Error> {
1513    match value.trim() {
1514      "U" => Ok(HitPolicy::Unique),
1515      "A" => Ok(HitPolicy::Any),
1516      "P" => Ok(HitPolicy::Priority),
1517      "F" => Ok(HitPolicy::First),
1518      "R" => Ok(HitPolicy::RuleOrder),
1519      "O" => Ok(HitPolicy::OutputOrder),
1520      "C" => Ok(HitPolicy::Collect(BuiltinAggregator::List)),
1521      "C+" => Ok(HitPolicy::Collect(BuiltinAggregator::Sum)),
1522      "C#" => Ok(HitPolicy::Collect(BuiltinAggregator::Count)),
1523      "C<" => Ok(HitPolicy::Collect(BuiltinAggregator::Min)),
1524      "C>" => Ok(HitPolicy::Collect(BuiltinAggregator::Max)),
1525      other => Err(err_invalid_decision_table_hit_policy(other)),
1526    }
1527  }
1528}
1529
1530/// Aggregator function for `COLLECT` [hit policy](HitPolicy).
1531#[derive(Debug, PartialEq, Eq, Copy, Clone)]
1532pub enum BuiltinAggregator {
1533  /// The result of the decision table is a list of output entries.
1534  List,
1535  /// The result of the decision table is the number of outputs.
1536  Count,
1537  /// The result of the decision table is the sum of all the outputs.
1538  Sum,
1539  /// The result of the decision table is the smallest value of all the outputs.
1540  Min,
1541  /// The result of the decision table is the largest value of all the outputs.
1542  Max,
1543}
1544
1545impl Display for BuiltinAggregator {
1546  /// Implements [Display] trait for [BuiltinAggregator].
1547  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1548    write!(
1549      f,
1550      "{}",
1551      match self {
1552        BuiltinAggregator::List => "C",
1553        BuiltinAggregator::Count => "C#",
1554        BuiltinAggregator::Sum => "C+",
1555        BuiltinAggregator::Min => "C<",
1556        BuiltinAggregator::Max => "C>",
1557      }
1558    )
1559  }
1560}
1561
1562#[derive(Debug, Clone, PartialEq, Eq)]
1563pub struct InputClause {
1564  /// The subject of this input clause, text representation of unary tests.
1565  pub input_expression: String,
1566  /// Optional unary tests that constrain the result of input expression of this input clause.
1567  pub allowed_input_values: Option<String>,
1568}
1569
1570#[derive(Debug, Clone, PartialEq, Eq)]
1571pub struct OutputClause {
1572  /// Type reference may specify the type to be used as decision table's output when more than one output clause is present.
1573  pub type_ref: Option<String>,
1574  /// The name of the output component when the decision table contains more than one output clause.
1575  pub name: Option<String>,
1576  /// Unary tests that constrain the result of output entries corresponding to this output clause.
1577  pub allowed_output_values: Option<String>,
1578  /// Default output expression, selected in incomplete table when no rules match for the decision table.
1579  pub default_output_entry: Option<String>,
1580}
1581
1582#[derive(Debug, Clone, PartialEq, Eq)]
1583pub struct RuleAnnotationClause {
1584  /// Name that is used as the name of the rule annotation column of the containing decision table.
1585  pub name: String,
1586}
1587
1588#[derive(Debug, Clone, PartialEq, Eq)]
1589pub struct DecisionRule {
1590  /// Ordered list of input entries that compose this decision rule.
1591  pub input_entries: Vec<InputEntry>,
1592  /// Ordered list of output entries that compose this decision rule.
1593  pub output_entries: Vec<OutputEntry>,
1594  /// Ordered list of rule annotations that compose this decision rule.
1595  pub annotation_entries: Vec<AnnotationEntry>,
1596}
1597
1598#[derive(Debug, Clone, PartialEq, Eq)]
1599pub struct InputEntry {
1600  /// Text representation of unary test that composes this input entry.
1601  pub text: String,
1602}
1603
1604#[derive(Debug, Clone, PartialEq, Eq)]
1605pub struct OutputEntry {
1606  /// Text representation of literal expression that composes this output entry.
1607  pub text: String,
1608}
1609
1610#[derive(Debug, Clone, PartialEq, Eq)]
1611pub struct AnnotationEntry {
1612  /// Text representing this rule annotation.
1613  pub text: String,
1614}
1615
1616/// [Dmndi] is a container for the shared [DmnStyle](DmnStyle)s
1617/// and all [DmnDiagram](DmnDiagram)s defined in [Definitions].
1618#[derive(Debug, Clone)]
1619pub struct Dmndi {
1620  /// A list of shared [DmnStyle] that can be referenced
1621  /// by all [DmnDiagram] and [DmnDiagramElement].
1622  pub styles: Vec<DmnStyle>,
1623  /// A list of [DmnDiagram].
1624  pub diagrams: Vec<DmnDiagram>,
1625}
1626
1627/// Defines possible elements of [DmnDiagramElement].
1628#[derive(Debug, Clone)]
1629pub enum DmnDiagramElement {
1630  DmnShape(DmnShape),
1631  DmnEdge(DmnEdge),
1632}
1633
1634/// [DmnDiagram] is the container of [DmnDiagramElement] ([DmnShape] (s) and [DmnEdge] (s)).
1635/// [DmnDiagram] cannot include other [DmnDiagrams](DmnDiagram).
1636#[derive(Debug, Clone, Default)]
1637pub struct DmnDiagram {
1638  /// [DmnDiagram] id.
1639  pub id: Option<String>,
1640  /// The name of the diagram. Default is empty [String].
1641  pub name: Option<String>,
1642  /// The documentation of the diagram. Default is empty [String].
1643  pub documentation: String,
1644  /// The resolution of the diagram expressed in user units per inch. Default is 300.
1645  pub resolution: f64,
1646  /// A list of [DmnDiagramElement] ([DmnShape] and [DmnEdge]) that are depicted in this diagram.
1647  pub diagram_elements: Vec<DmnDiagramElement>,
1648  /// A reference to a [DmnStyle] defined in the [Dmndi] that serves as the default styling
1649  /// of the [DmnDiagramElement] in this [DmnDiagram].
1650  pub shared_style: Option<String>,
1651  /// A [DmnStyle] that defines the default styling for this diagram.
1652  /// Properties defined in that style override the ones in the 'sharedStyle'.
1653  pub local_style: Option<DmnStyle>,
1654  /// The size of this diagram. If not specified, the [DmnDiagram] is unbounded.
1655  pub size: Option<DcDimension>,
1656}
1657
1658/// [DmnShape] represents a [Decision], a [BusinessKnowledgeModel], an [InputData] element,
1659/// a [KnowledgeSource], a [DecisionService] or a [TextAnnotation] that is depicted on the diagram.
1660#[derive(Debug, Clone)]
1661pub struct DmnShape {
1662  /// Unique identifier of this [DmnShape].
1663  pub id: Option<String>,
1664  /// The [DcBounds] of the shape relative to the origin of its parent [DmnDiagram]. The [DcBounds] MUST be specified.
1665  pub bounds: DcBounds,
1666  /// A  reference  to  a  [Decision], a [BusinessKnowledgeModel], an [InputData] element,
1667  /// a [KnowledgeSource], a [DecisionService] or a [TextAnnotation] MUST be specified.
1668  pub dmn_element_ref: Option<String>,
1669  /// If the [DmnShape] depicts an [InputData] element then this attribute is used to determine
1670  /// if the [InputData] is listed on the [Decision] element (true) or drawn as separate notational elements in the DRD (false).
1671  pub is_listed_input_data: bool,
1672  /// If the [DmnShape] depicts a [DecisionService], this attribute references a [DmnDecisionServiceDividerLine] that defines,
1673  /// where the [DmnShape] is divided into two parts by a straight solid line.
1674  /// This can be the case when a [DmnShape] depicts a [DecisionService],
1675  /// where the set of output decisions is smaller than the set of encapsulated decisions.
1676  /// The start and end waypoints of the `decisionServiceDividerLine` **MUST** be on the border of the [DmnShape].
1677  pub decision_service_divider_line: Option<DmnDecisionServiceDividerLine>,
1678  /// If the [DmnShape] depicts a [DecisionService], this attribute indicates
1679  /// if it should be depicted expanded (`false`) or collapsed (`true`).
1680  /// Default is `false`.
1681  pub is_collapsed: bool,
1682  /// A reference to a [DmnStyle] defined in the [Dmndi].
1683  pub shared_style: Option<String>,
1684  /// A [DmnStyle] that defines the styling for this element.
1685  pub local_style: Option<DmnStyle>,
1686  /// An optional label when this [DmnElement] has a visible text label.
1687  pub label: Option<DmnLabel>,
1688}
1689
1690/// Struct defines line inside [DecisionService].
1691#[derive(Debug, Clone)]
1692pub struct DmnDecisionServiceDividerLine {
1693  pub id: Option<String>,
1694  /// A list of points relative to the origin of its parent [DmnDiagram] that specifies
1695  /// the connected line segments of the edge. At least two (2) waypoint`s MUST be specified.
1696  /// Waypoint must be on the border of the [DmnShape].
1697  pub way_points: Vec<DcPoint>,
1698  /// A reference to a [DmnStyle] defined in the [Dmndi].
1699  pub shared_style: Option<String>,
1700  /// A [DmnStyle] that defines the styling for this element.
1701  pub local_style: Option<DmnStyle>,
1702}
1703
1704#[derive(Debug, Clone)]
1705pub struct DmnEdge {
1706  pub id: Option<String>,
1707  /// A list of points relative to the origin of its parent [DmnDiagram] that specifies
1708  /// the connected line segments of the edge. At least two (2) waypoints MUST be specified.
1709  pub way_points: Vec<DcPoint>,
1710  /// A reference to a [InformationRequirement], [KnowledgeRequirement],
1711  /// [AuthorityRequirement] or an [Association], MUST be specified.
1712  pub dmn_element_ref: Option<String>,
1713  /// The actual [DmnDiagramElement] this [DmnEdge] is connecting from.
1714  /// MUST be specified when the [DmnEdge] has a source.
1715  pub source_element: Option<String>,
1716  /// The actual [DmnDiagramElement] this [DmnEdge] is connecting to.
1717  /// MUST be specified when the [DmnEdge] has a target.
1718  pub target_element: Option<String>,
1719  /// A reference to a [DmnStyle] defined in the [Dmndi].
1720  pub shared_style: Option<String>,
1721  /// A [DmnStyle] that defines the styling for this element.
1722  pub local_style: Option<DmnStyle>,
1723  /// An optional label when this [DmnElement] has a visible text label.
1724  pub label: Option<DmnLabel>,
1725}
1726
1727//FIXME verify this struct
1728/// tdb
1729#[derive(Debug, Clone)]
1730pub struct Association {}
1731
1732//FIXME verify this struct
1733/// tdb
1734#[derive(Debug, Clone)]
1735pub struct TextAnnotation {}
1736
1737/// [DmnStyle] is used to keep some non-normative visual attributes such as color and font.
1738#[derive(Debug, Clone)]
1739pub struct DmnStyle {
1740  /// A unique identifier for this style so it can be referenced.
1741  /// Only styles defined in the [Dmndi] can be referenced by [DmnDiagramElement] and [DmnDiagram].
1742  pub id: String,
1743  /// The color use to fill the shape.Does not apply to [DmnEdge]. Default is `white`.
1744  pub fill_color: Option<DcColor>,
1745  /// The color use to draw the shape borders. Default is `black`.
1746  pub stroke_color: Option<DcColor>,
1747  /// The color use to draw the label. Default is `black`.
1748  pub font_color: Option<DcColor>,
1749  /// A comma-separated list of Font Name that can be used to display the text. Default is `Arial`.
1750  pub font_family: Option<String>,
1751  /// The size in points of the font to use to display the text. Default is `8` points.
1752  pub font_size: Option<f64>,
1753  /// If the text should be displayed in Italic. Default is `false`.
1754  pub font_italic: Option<bool>,
1755  /// If the text should be displayed in Bold. Default is `false`.
1756  pub font_bold: Option<bool>,
1757  /// If the text should be underlined. Default is `false`.
1758  pub font_underline: Option<bool>,
1759  /// If the text should be stroked through. Default is `false`.
1760  pub font_strike_through: Option<bool>,
1761  /// How text should be positioned horizontally within the Label bounds.
1762  /// Default depends on the [DmnDiagramElement] the label is attached to (see 13.5).
1763  pub label_horizontal_alignment: Option<DcAlignmentKind>,
1764  /// How  the  text  should  be  positioned  vertically  inside  the  Label  bounds.
1765  /// Default depends on the [DmnDiagramElement] the label is attached to (see 13.5).
1766  /// Start means `top` and end means `bottom`.
1767  pub label_vertical_alignment: Option<DcAlignmentKind>,
1768}
1769
1770/// Struct represents the depiction of some textual information about a DMN element.
1771#[derive(Debug, Clone)]
1772pub struct DmnLabel {
1773  /// The bounds of the [DmnLabel]. When not specified, the label is positioned
1774  /// at its default position as determined in clause 13.5.
1775  pub bounds: Option<DcBounds>,
1776  /// An optional pretty printed text that MUST be displayed
1777  /// instead of the [DmnElement's](DmnElement) name if it is present.
1778  pub text: Option<String>,
1779  /// A reference to a [DmnStyle] defined in the [Dmndi].
1780  pub shared_style: Option<String>,
1781}
1782
1783/// Defines RGB color.
1784#[derive(Debug, Copy, Clone)]
1785pub struct DcColor {
1786  pub red: u8,
1787  pub green: u8,
1788  pub blue: u8,
1789}
1790
1791impl DcColor {
1792  pub fn white() -> Self {
1793    Self {
1794      red: 0xFF,
1795      green: 0xFF,
1796      blue: 0xFF,
1797    }
1798  }
1799
1800  pub fn black() -> Self {
1801    Self { red: 0x0, green: 0x0, blue: 0x0 }
1802  }
1803}
1804
1805/// Defines point.
1806#[derive(Debug, Copy, Clone)]
1807pub struct DcPoint {
1808  pub x: f64,
1809  pub y: f64,
1810}
1811
1812/// Defines bounds.
1813#[derive(Debug, Copy, Clone)]
1814pub struct DcBounds {
1815  pub x: f64,
1816  pub y: f64,
1817  pub width: f64,
1818  pub height: f64,
1819}
1820
1821/// Defines dimensions.
1822#[derive(Debug, Copy, Clone)]
1823pub struct DcDimension {
1824  pub width: f64,
1825  pub height: f64,
1826}
1827
1828/// Defines the kind of element alignment.
1829#[derive(Debug, Copy, Clone)]
1830pub enum DcAlignmentKind {
1831  /// Left or top.
1832  Start,
1833  /// Right or bottom.
1834  End,
1835  /// Center or middle.
1836  Center,
1837}
1838
1839/// Defines known colors.
1840#[derive(Debug, Copy, Clone)]
1841pub enum DcKnownColor {
1842  Aqua = 0x00FFFF,
1843  Black = 0x000000,
1844  Blue = 0x0000FF,
1845  Fuchsia = 0xFF00FF,
1846  Gray = 0x808080,
1847  Green = 0x008000,
1848  Lime = 0x00FF00,
1849  Maroon = 0x800000,
1850  Navy = 0x000080,
1851  Olive = 0x808000,
1852  Orange = 0xFFA500,
1853  Purple = 0x800080,
1854  Red = 0xFF0000,
1855  Silver = 0xC0C0C0,
1856  Teal = 0x008080,
1857  White = 0xFFFFFF,
1858  Yellow = 0xFFFF00,
1859}