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}