forester_rs/tree/parser/ast/
arg.rs

1use crate::tree::parser::ast::arg::ArgumentsType::{Named, Unnamed};
2use crate::tree::parser::ast::call::Call;
3use crate::tree::parser::ast::message::Message;
4use crate::tree::parser::ast::Key;
5use crate::tree::{cerr, TreeError};
6use itertools::Itertools;
7use serde::{Deserialize, Serialize};
8use std::fmt::{Display, Formatter};
9
10/// Just a pair of name and type
11/// This is a representation of a tree parameter
12/// # Example
13/// `sequence tree(a:string){...}`
14/// and a:string is a param
15#[derive(Clone, Debug, PartialEq)]
16pub struct Param {
17    pub name: Key,
18    pub tpe: MesType,
19}
20
21impl Display for Param {
22    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
23        write!(f, "{}:{}", self.name, self.tpe)
24    }
25}
26
27impl Param {
28    pub fn new(id: &str, tpe: MesType) -> Self {
29        Param {
30            name: id.to_string(),
31            tpe,
32        }
33    }
34}
35
36#[derive(Clone, Debug, Default, PartialEq)]
37pub struct Params {
38    pub params: Vec<Param>,
39}
40
41impl Params {
42    pub fn new(params: Vec<Param>) -> Self {
43        Params { params }
44    }
45}
46
47/// The right part of the argument
48#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
49pub enum ArgumentRhs {
50    /// A pointer to the bb key or the parameter from the parent tree
51    Id(Key),
52    /// A scalar value
53    Mes(Message),
54    /// A call to a tree
55    Call(Call),
56}
57
58impl ArgumentRhs {
59    pub fn get_call(&self) -> Option<Call> {
60        match self {
61            ArgumentRhs::Call(call) => Some(call.clone()),
62            _ => None,
63        }
64    }
65}
66
67impl Display for ArgumentRhs {
68    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
69        match self {
70            ArgumentRhs::Id(id) => write!(f, "&{}", id),
71            ArgumentRhs::Mes(m) => write!(f, "{}", m),
72            ArgumentRhs::Call(c) => match c {
73                Call::Invocation(name, args) => {
74                    write!(f, "{}({})", name, args)
75                }
76                Call::HoInvocation(name) => {
77                    write!(f, "{}(..)", name)
78                }
79                Call::Lambda(tpe, _) => {
80                    write!(f, "{}...", tpe)
81                }
82                Call::Decorator(tpe, args, _call) => {
83                    write!(f, "{}({})...", tpe, args)
84                }
85            },
86        }
87    }
88}
89
90/// An argument is a pair of name and value or just a value
91#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
92pub enum Argument {
93    Assigned(Key, ArgumentRhs),
94    Unassigned(ArgumentRhs),
95}
96
97impl Argument {
98    pub fn has_name(&self, key: &Key) -> bool {
99        matches!(self, Argument::Assigned(k, _) if k == key)
100    }
101
102    pub fn name(&self) -> Option<&Key> {
103        match self {
104            Argument::Assigned(k, _) => Some(k),
105            Argument::Unassigned(_) => None,
106        }
107    }
108
109    pub fn value(&self) -> &ArgumentRhs {
110        match self {
111            Argument::Assigned(_, v) | Argument::Unassigned(v) => v,
112        }
113    }
114}
115
116impl Display for Argument {
117    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
118        match self {
119            Argument::Assigned(k, rhs) => write!(f, "{}={}", k, rhs),
120            Argument::Unassigned(rhs) => write!(f, "{}", rhs),
121        }
122    }
123}
124
125impl Argument {
126    pub fn id(v: &str) -> Self {
127        Argument::Unassigned(ArgumentRhs::Id(v.to_string()))
128    }
129    pub fn mes(v: Message) -> Self {
130        Argument::Unassigned(ArgumentRhs::Mes(v))
131    }
132    pub fn call(v: Call) -> Self {
133        Argument::Unassigned(ArgumentRhs::Call(v))
134    }
135    pub fn id_id(lhs: &str, rhs: &str) -> Self {
136        Argument::Assigned(lhs.to_string(), ArgumentRhs::Id(rhs.to_string()))
137    }
138    pub fn id_mes(lhs: &str, rhs: Message) -> Self {
139        Argument::Assigned(lhs.to_string(), ArgumentRhs::Mes(rhs))
140    }
141    pub fn id_call(lhs: &str, rhs: Call) -> Self {
142        Argument::Assigned(lhs.to_string(), ArgumentRhs::Call(rhs))
143    }
144}
145
146#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
147pub struct Arguments {
148    pub args: Vec<Argument>,
149}
150
151/// this is a plain representation of the argument type
152/// to avoid several levels of nesting
153pub enum ArgumentsType {
154    Unnamed,
155    Named,
156    Empty,
157}
158
159impl Arguments {
160
161    pub fn get_type(&self) -> Result<ArgumentsType, TreeError> {
162        let mut curr = None;
163
164        for a in &self.args {
165            match (a, &curr) {
166                (Argument::Assigned(_, _), None) => curr = Some(Named),
167                (Argument::Unassigned(_), None) => curr = Some(Unnamed),
168                (Argument::Assigned(_, _), Some(Named)) => {}
169                (Argument::Unassigned(_), Some(Unnamed)) => {}
170                _ => {
171                    return Err(cerr(
172                        format!("the arguments ({}) should be either named ot unnamed but not a mix",self)
173                    ))
174                }
175            }
176        }
177        Ok(curr.unwrap_or(ArgumentsType::Empty))
178    }
179}
180
181impl Display for Arguments {
182    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
183        let str = &self.args.iter().map(|a| format!("{}", a)).join(",");
184        write!(f, "{}", str)
185    }
186}
187
188impl Arguments {
189    pub fn new(args: Vec<Argument>) -> Self {
190        Self { args }
191    }
192}
193
194#[derive(Clone, Debug, PartialEq)]
195pub enum MesType {
196    Any,
197    Num,
198    Array,
199    Object,
200    String,
201    Bool,
202    Tree,
203}
204
205impl Display for MesType {
206    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
207        match self {
208            MesType::Any => write!(f, "any"),
209            MesType::Num => write!(f, "num"),
210            MesType::Array => write!(f, "array"),
211            MesType::Object => write!(f, "object"),
212            MesType::String => write!(f, "string"),
213            MesType::Bool => write!(f, "bool"),
214            MesType::Tree => write!(f, "tree"),
215        }
216    }
217}