chrono_node/core/
configuration.rs1use std::sync::Arc;
10
11use super::chrono::{Chrono, NamedParser, NamedRefiner, Parser, Refiner};
12use super::registry::{find_parser, find_refiner};
13
14#[derive(Clone, Debug, Default, PartialEq, Eq)]
16pub struct Flags(Vec<(&'static str, bool)>);
17
18impl Flags {
19 pub fn none() -> Flags {
20 Flags(Vec::new())
21 }
22
23 pub fn of(pairs: &[(&'static str, bool)]) -> Flags {
24 Flags(pairs.to_vec())
25 }
26
27 pub fn get(&self, name: &str) -> bool {
29 self.0.iter().find(|(k, _)| *k == name).is_some_and(|(_, v)| *v)
30 }
31
32 pub fn iter(&self) -> impl Iterator<Item = (&'static str, bool)> + '_ {
33 self.0.iter().copied()
34 }
35}
36
37#[derive(Clone, Debug, PartialEq, Eq)]
39pub struct Slot {
40 pub name: &'static str,
41 pub flags: Flags,
42}
43
44#[derive(Clone, Debug, Default, PartialEq, Eq)]
46pub struct Configuration {
47 pub parsers: Vec<Slot>,
48 pub refiners: Vec<Slot>,
49}
50
51impl Configuration {
52 pub fn push_parser(&mut self, name: &'static str, flags: Flags) {
53 self.parsers.push(Slot { name, flags });
54 }
55 pub fn unshift_parser(&mut self, name: &'static str, flags: Flags) {
56 self.parsers.insert(0, Slot { name, flags });
57 }
58 pub fn push_refiner(&mut self, name: &'static str, flags: Flags) {
59 self.refiners.push(Slot { name, flags });
60 }
61 pub fn unshift_refiner(&mut self, name: &'static str, flags: Flags) {
62 self.refiners.insert(0, Slot { name, flags });
63 }
64 pub fn remove_refiners(&mut self, name: &str) {
67 self.refiners.retain(|slot| slot.name != name);
68 }
69
70 pub fn build(&self) -> Chrono {
72 let mut chrono = Chrono::default();
73 for slot in &self.parsers {
74 match find_parser(slot.name) {
75 Some(entry) => {
76 let parser: Arc<dyn Parser> = Arc::from((entry.create)(&slot.flags));
77 chrono.parsers.push(NamedParser {
78 name: slot.name,
79 flags: slot.flags.clone(),
80 parser,
81 });
82 }
83 None => chrono.missing.push(slot.name),
84 }
85 }
86 for slot in &self.refiners {
87 match find_refiner(slot.name) {
88 Some(entry) => {
89 let refiner: Arc<dyn Refiner> = Arc::from((entry.create)(&slot.flags));
90 chrono.refiners.push(NamedRefiner {
91 name: slot.name,
92 flags: slot.flags.clone(),
93 refiner,
94 });
95 }
96 None => chrono.missing.push(slot.name),
97 }
98 }
99 chrono
100 }
101}