automata_like_programming/simple_impl/series/
definer.rs1use std::{rc::Rc, sync::Arc};
2
3use crate::simple_impl::simple_state::{KeyProvidingData, SharedSimpleState, SimpleInterStateConnection};
4
5pub struct SeriesDefiner<'a, K, Id: Copy, D: KeyProvidingData<K>, E> {
49 default_state: SharedSimpleState<'a, K, Id, D, E>,
50 default_execution: Arc<dyn Fn(&mut D, &K) -> Result<(), E> + 'a>,
51 state: SharedSimpleState<'a, K, Id, D, E>,
53}
54
55impl <'a, K, Id: Copy, D: KeyProvidingData<K>, E> SeriesDefiner<'a, K, Id, D, E> {
56 pub fn new_without_default_action(starting_state: &SharedSimpleState<'a, K, Id, D, E>) -> SeriesDefiner<'a, K, Id, D, E> {
58 Self::new(starting_state, |_, _| {Result::Ok(())})
59 }
60
61 pub fn new<FDExec: Fn(&mut D, &K) -> Result<(), E> + 'a>(starting_state: &SharedSimpleState<'a, K, Id, D, E>, default_execution_function: FDExec) -> SeriesDefiner<'a, K, Id, D, E> {
63 Self::new_different_default_state(starting_state, starting_state, default_execution_function)
64 }
65
66 pub fn new_different_default_state<FDExec: Fn(&mut D, &K) -> Result<(), E> + 'a>(starting_state: &SharedSimpleState<'a, K, Id, D, E>, default_state: &SharedSimpleState<'a, K, Id, D, E>, default_execution_function: FDExec) -> SeriesDefiner<'a, K, Id, D, E> {
68 SeriesDefiner {
69 state: Rc::clone(&starting_state),
70 default_state: Rc::clone(&default_state),
71 default_execution: Arc::new(default_execution_function),
72 }
73 }
74
75 pub fn next_state<M>(mut self, matcher: M, next_state: &SharedSimpleState<'a, K, Id, D, E>) -> SeriesDefiner<'a, K, Id, D, E>
78 where M: 'a + Fn(&K) -> bool
79 {
80 self.state.borrow_mut().register_connection(SimpleInterStateConnection::new_no_action(matcher, next_state));
81 let default_exec_function = Arc::clone(&self.default_execution);
82 self.state.borrow_mut().register_connection(SimpleInterStateConnection::new_always_matched(move |k,d| (default_exec_function)(k, d), &self.default_state));
83 self.state = Rc::clone(next_state);
84 self
85 }
86
87 pub fn next_state_exec<M, FExec>(mut self, matcher: M, next_state: &SharedSimpleState<'a, K, Id, D, E>, execution_function: FExec) -> SeriesDefiner<'a, K, Id, D, E>
90 where
91 M: 'a + Fn(&K) -> bool,
92 FExec: 'a + Fn(&mut D, &K) -> Result<(), E>
93 {
94 self.state.borrow_mut().register_connection(SimpleInterStateConnection::new(matcher, execution_function, next_state));
95 let default_exec_function = Arc::clone(&self.default_execution);
96 self.state.borrow_mut().register_connection(SimpleInterStateConnection::new_always_matched(move |k,d| (default_exec_function)(k, d), &self.default_state));
97 self.state = Rc::clone(next_state);
98 self
99 }
100}
101
102#[cfg(test)]
103mod test {
104 use std::{cell::RefCell, rc::Rc};
105
106 use crate::{automaton::{Automaton, AutomatonResult}, automaton_state::{new_shared_concrete_state, AutomatonState}, simple_impl::simple_state::SimpleStateImplementation, test_commons::{char_matcher, unwrap_result, CopiedTestData}};
107
108 use super::SeriesDefiner;
109
110 fn create_abc_series_state_tree() -> Rc<RefCell<dyn AutomatonState<'static, char, CopiedTestData<char>, String>>> {
111 let root_state = new_shared_concrete_state(SimpleStateImplementation::new('x'));
112 SeriesDefiner::new(&root_state, |_, _| {Result::Ok(())})
113 .next_state(char_matcher('a'), &new_shared_concrete_state(SimpleStateImplementation::new('a')))
114 .next_state(char_matcher('b'), &new_shared_concrete_state(SimpleStateImplementation::new('b')))
115 .next_state(char_matcher('c'), &new_shared_concrete_state(SimpleStateImplementation::new('c')));
116 root_state
117 }
118
119 #[test]
120 fn series_full_match() -> () {
121 let mut automaton = Automaton::new(create_abc_series_state_tree());
122 let mut data = CopiedTestData::new(vec!['a', 'b', 'c']);
123 let automaton_result: AutomatonResult<char, String> = automaton.run(&mut data);
124 assert_eq!(unwrap_result!(automaton_result.expect_empty_iter()), 'c');
125 }
126
127 #[test]
128 fn series_back_to_default() -> () {
129 let mut automaton = Automaton::new(create_abc_series_state_tree());
130 let mut data = CopiedTestData::new(vec!['a', 'b', 'd']);
131 let automaton_result: AutomatonResult<char, String> = automaton.run(&mut data);
132 assert_eq!(unwrap_result!(automaton_result.expect_empty_iter()), 'x');
133 }
134
135 #[test]
136 fn series_no_more_sates() -> () {
137 let mut automaton = Automaton::new(create_abc_series_state_tree());
138 let mut data = CopiedTestData::new(vec!['a', 'b', 'c', 'd']);
139 let automaton_result = automaton.run(&mut data).expect_could_not_find_next_state();
140 assert_eq!(unwrap_result!(automaton_result), 'c');
141 }
142}