1use crate::error::{EngineError, MyError, MyResult};
2use crate::interface::{Directive, Interface, Operation};
3use crate::value::Value;
4use std::cell::RefCell;
5use std::io::Write;
6use std::rc::Rc;
7
8pub enum Action<W: Write> {
9 Operation(Rc<Operation<W>>),
10 Directive(Rc<Directive<W>>, Vec<String>),
11 Definition(Vec<Action<W>>),
12 Value(Value),
13}
14
15impl<W: Write> Clone for Action<W> {
16 fn clone(&self) -> Self {
17 match self {
18 Self::Operation(operation) => Self::Operation(operation.clone()),
19 Self::Directive(directive, tokens) => Self::Directive(directive.clone(), tokens.clone()),
20 Self::Definition(actions) => Self::Definition(actions.clone()),
21 Self::Value(value) => Self::Value(value.clone()),
22 }
23 }
24}
25
26pub struct Actions<'a, W: Write, I: Iterator<Item = &'a str>> {
27 interface: Rc<RefCell<Interface<W>>>,
28 tokens: I,
29}
30
31impl<'a, W: Write, I: Iterator<Item = &'a str>> Actions<'a, W, I> {
32 pub fn new(
33 interface: &Rc<RefCell<Interface<W>>>,
34 tokens: I,
35 ) -> Self {
36 let interface = Rc::clone(interface);
37 Self { interface, tokens }
38 }
39}
40
41impl<'a, W: Write, I: Iterator<Item = &'a str>> Iterator for Actions<'a, W, I> {
43 type Item = MyResult<(Action<W>, &'a str)>;
44
45 fn next(&mut self) -> Option<Self::Item> {
46 if let Some(token) = self.tokens.next() {
47 let interface = self.interface.borrow();
48 if let Some(operation) = interface.get_operation(token) {
49 let action = Action::Operation(operation);
50 return Some(Ok((action, token)));
51 } else if let Some(directive) = interface.get_directive(token) {
52 let mut tokens = Vec::new();
53 while let Some(token) = self.tokens.next() {
54 tokens.push(String::from(token));
55 }
56 let action = Action::Directive(directive, tokens);
57 return Some(Ok((action, token)));
58 } else if let Some(actions) = interface.get_definition(token) {
59 let action = Action::Definition(actions);
60 return Some(Ok((action, token)));
61 } else {
62 match Value::from_string(token) {
63 Ok(value) => {
64 let action = Action::Value(value);
65 return Some(Ok((action, token)));
66 }
67 Err(_) => {
68 let error = EngineError::ParseError(String::from(token));
69 return Some(Err(MyError::from(error)));
70 }
71 }
72 }
73 }
74 None
75 }
76}