1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
pub( crate ) mod private
{
  use std::collections::HashMap;

  /// Represents a program that contains one or more namespaces, where each namespace contains a list of commands.
  ///
  /// A `Program` consists of one or more Namespaces, where each namespace contains a list of commands. The `Namespace` can be any type that represents a namespace of commands, such as `RawCommand`, `GrammarCommand`, or `ExecutableCommand`.
  ///
  /// The program can be executed by iterating over each namespace and executing its commands sequentially or in parallel.
  ///
  /// # Example:
  ///
  /// ```
  /// # use wca::{ RawCommand, Namespace, Program };
  /// # use std::collections::HashMap;
  /// let namespace1 = Namespace
  /// {
  ///   commands : vec!
  ///   [
  ///     RawCommand
  ///     {
  ///       name : "cmd1".to_string(),
  ///       subjects : vec![ "sub1".to_string() ],
  ///       properties: HashMap::new(),
  ///     },
  ///     RawCommand
  ///     {
  ///       name: "cmd2".to_string(),
  ///       subjects: vec![ "sub2".to_string(), "sub3".to_string() ],
  ///       properties: HashMap::new(),
  ///     },
  ///   ],
  /// };
  ///
  /// let namespace2 = Namespace
  /// {
  ///   commands : vec!
  ///   [
  ///     RawCommand
  ///     {
  ///       name : "cmd1".to_string(),
  ///       subjects : vec![ "sub1".to_string() ],
  ///       properties: HashMap::new(),
  ///     },
  ///   ],
  /// };
  /// let program = Program { namespaces : vec![ namespace1, namespace2, /* ... */ ] };
  /// ```
  ///
  /// In the above example, a Program is created with two Namespace objects. Each namespace contains a different set of RawCommand objects with different sets of subjects. The Program can be executed by iterating over each namespace and executing its commands in sequence.
  ///
  #[ derive( Debug, Clone, PartialEq, Eq ) ]
  pub struct Program< Namespace >
  {
    /// list of namespaces with commands
    pub namespaces : Vec< Namespace >,
  }

  /// Represents a namespace of commands with the specified Command type. This is done to be flexible and not to duplicate code.
  ///
  /// A `Namespace` contains a list of commands, where each command can be a `RawCommand`, `GrammarCommand`, `ExecutableCommand`, or any other command type that you define.
  ///
  /// In the future, each namespace can be executed in parallel. This means that commands in namespace will be executed synchronous but each namespace can be executed in parallel to each other.
  ///
  /// # Example:
  ///
  /// ```
  /// # use wca::RawCommand;
  /// # use wca::Namespace;
  /// # use std::collections::HashMap;
  ///
  /// let commands = vec!
  /// [
  ///     RawCommand
  ///     {
  ///         name: "cmd1".to_string(),
  ///         subjects: vec![ "sub1".to_string() ],
  ///         properties: HashMap::new(),
  ///     },
  ///     RawCommand
  ///     {
  ///         name: "cmd2".to_string(),
  ///         subjects: vec![ "sub2".to_string(), "sub3".to_string() ],
  ///         properties: HashMap::new(),
  ///     },
  ///     RawCommand
  ///     {
  ///         name: "cmd3".to_string(),
  ///         subjects: vec![],
  ///         properties: HashMap::new(),
  ///     },
  ///     /* ... */
  /// ];
  ///
  /// let namespace = Namespace { commands };
  /// ```
  ///
  /// In the above example, a `Namespace` is created with three `RawCommand` objects. Each command has a different set of subjects.
  ///
  #[ derive( Debug, Clone, PartialEq, Eq ) ]
  pub struct Namespace< Command >
  {
      /// list of commands
      pub commands : Vec< Command >,
  }

  /// Represents a parsed command that has been extracted from an input string by a `Parser`.
  ///
  /// The `RawCommand` struct is designed to be flexible and allow for a wide variety of commands to be parsed and represented. However, this flexibility also means that a `RawCommand` may contain invalid or unexpected data.
  ///
  /// # Example:
  ///
  /// ```
  /// # use wca::RawCommand;
  /// # use std::collections::HashMap;
  /// RawCommand
  /// {
  ///   name : "command".to_string(),
  ///   subjects : vec![ "subject_value".to_string(), /* ... */ ],
  ///   properties : HashMap::from_iter(
  ///   [
  ///     ( "prop_name".to_string(), "raw_prop_value".to_string() ),
  ///     /* ... */
  ///   ])
  /// };
  /// ```
  ///
  /// In the above example, a `RawCommand` instance is created with the name "command", a single subject "subject_value", and one property "prop_name" with a raw value of "raw_prop_value".
  ///
  #[ derive( Default, Debug, Clone, PartialEq, Eq ) ]
  pub struct RawCommand
  {
    /// name of command without delimiter
    pub name : String,
    /// list of all subjects for the command
    pub subjects : Vec< String >,
    /// dictionary of properties. Each property has a name and a raw value
    pub properties : HashMap< String, String >
  }
}

//

crate::mod_interface!
{
  exposed use Program;
  exposed use Namespace;
  exposed use RawCommand;
}