automata_like_programming/simple_impl/series/
builder.rs

1use crate::{automaton_state::new_shared_concrete_state, simple_impl::simple_state::{KeyProvidingData, SharedSimpleState, SimpleStateImplementation}};
2
3use super::definer::SeriesDefiner;
4
5/// Allows for quick definition of chain of states that follow single path.
6/// # Examples
7/// ```
8/// # use std::{cell::RefCell, rc::Rc};
9/// # use automata_like_programming::{
10/// #   automaton::{
11/// #     AutomatonResult
12/// #   }, 
13/// #   automaton_state::{
14/// #     new_shared_concrete_state,
15/// #     AutomatonState
16/// #   }, 
17/// #   simple_impl::{
18/// #     series::builder::SeriesBuilder,
19/// #     simple_state::{
20/// #       KeyProvidingData,
21/// #       SimpleStateImplementation
22/// #     }
23/// #   }
24/// # };
25/// #
26/// # fn char_matcher(c: char) -> impl Fn(&char) -> bool {
27/// #   move |k: &char| *k == c
28/// # }
29/// #
30/// # pub struct TestData {}
31/// #
32/// # impl KeyProvidingData<char> for TestData {
33/// #   fn next_key(&mut self) -> Option<char> {
34/// #     Option::Some('a')
35/// #   }
36/// # }
37/// #
38/// // Creates series of state that will match 'abc' character sequence or go back to root state anytime there is a mismatch.
39/// fn create_abc_series_state_tree() -> Rc<RefCell<dyn AutomatonState<'static, char, TestData, String>>> {
40///   SeriesBuilder::new_without_default_action(SimpleStateImplementation::new('x'))
41///   .next_state(char_matcher('a'), SimpleStateImplementation::new('a'))
42///   .next_state(char_matcher('b'), SimpleStateImplementation::new('b'))
43///   .next_state(char_matcher('c'), SimpleStateImplementation::new('c'))
44///   .build()
45/// }
46/// ```
47pub struct SeriesBuilder<'a, K, Id: Copy, D: KeyProvidingData<K>, E> {
48    root: SharedSimpleState<'a, K, Id, D, E>,
49    definer: SeriesDefiner<'a, K, Id, D, E>,
50}
51
52impl <'a, K, Id: Copy, D: KeyProvidingData<K>, E> SeriesBuilder<'a, K, Id, D, E> {
53    pub fn new_without_default_action(root: SimpleStateImplementation<'a, K, Id, D, E>) -> SeriesBuilder<'a, K, Id, D, E> {
54        let root_shared = new_shared_concrete_state(root);
55        SeriesBuilder {
56            definer: SeriesDefiner::new_without_default_action(&root_shared),
57            root: root_shared,
58        }
59    }
60
61    pub fn new<FDExec: Fn(&mut D, &K) -> Result<(), E> + 'a>(root: SimpleStateImplementation<'a, K, Id, D, E>, default_execution_function: FDExec) -> SeriesBuilder<'a, K, Id, D, E> {
62        let root_shared = new_shared_concrete_state(root);
63        SeriesBuilder {
64            definer: SeriesDefiner::new(&root_shared, default_execution_function),
65            root: root_shared,
66        }
67    }
68
69    /// Creates new shared simple state and adds new connection to last added state with given matcher.
70    pub fn next_state<M>(mut self, matcher: M, next_state: SimpleStateImplementation<'a, K, Id, D, E>) -> SeriesBuilder<'a, K, Id, D, E> 
71    where M: 'a + Fn(&K) -> bool
72    {
73        let next_state_shared = new_shared_concrete_state(next_state);
74        self.definer = self.definer.next_state(matcher, &next_state_shared);
75        self
76    }
77
78    /// WARNING: Passed state will be modified after creating next connection, even before `build()` is called. Use with caution.
79    /// Creates connection from last appended state to specified state.
80    pub fn next_state_external<M>(mut self, matcher: M, next_state: &SharedSimpleState<'a, K, Id, D, E>) -> SeriesBuilder<'a, K, Id, D, E> 
81    where M: 'a + Fn(&K) -> bool
82    {
83        self.definer = self.definer.next_state(matcher, next_state);
84        self
85    }
86
87    /// Consumes builder and returns root state.
88    pub fn build(self) -> SharedSimpleState<'a, K, Id, D, E> {
89        self.root
90    }
91}