context_weaver/
lib.rs

1use core::processors::{PluginBridge, ProcessorRegistry};
2use std::fmt::Debug;
3
4use parser::parse_entry_content;
5
6pub mod core;
7pub mod types;
8pub mod errors;
9mod parser;
10mod tests;
11
12pub use types::WorldInfoType;
13pub use errors::{ParserError, WorldInfoError};
14
15
16
17pub struct WorldInfo<P: PluginBridge + 'static> {
18    name: String,
19    entries: Vec<WorldInfoEntry>,
20    /// List of allowed processors
21    permitted_processors: Vec<String>,
22    processor_registry: Box<ProcessorRegistry<P>>,
23    error_stack: Vec<WorldInfoError>,
24}
25
26impl<P: PluginBridge> WorldInfo<P>{
27    pub fn evaluate(&mut self) -> Result<String, &Vec<WorldInfoError>> {
28        let mut result = String::new();
29        let mut failed = false;
30        for entry in &mut self.entries {
31            match entry.parse(&self.processor_registry) {
32                Ok(_) => (),
33                Err(e) => {
34                    self.error_stack.push(e);
35                    failed = true;
36                }
37            }
38
39            if failed {
40                break;
41            }
42            
43            match entry.evalute() {
44                Ok(content) => result.push_str(&content),
45                Err(e) => {
46                    failed = true;
47                    self.error_stack.push(e)
48                },
49            }
50        }
51        
52        if failed {
53            Err(&self.error_stack)
54        } else {
55            Ok(result)
56        }
57    }
58}
59
60pub trait WorldInfoFactory<P: PluginBridge> {
61    /// Creates a new empty world info
62    fn new(registry: Box<ProcessorRegistry<P>>) -> Self;
63    /// Sets the name of the world info
64    fn set_name(&mut self, name: &str) -> &mut Self;
65    /// Inserts a world info entry
66    fn insert_entry(&mut self, entry: WorldInfoEntry) -> &mut Self;
67    /// Sets the list of permitted processors
68    fn set_permitted_processors(&mut self, processors: Vec<String>) -> &mut Self;
69    /// Builds the world info
70    fn build(&self) -> &Self;
71
72    /// Inserts a list of world info entries
73    fn insert_entries(&mut self, entries: Vec<WorldInfoEntry>) -> &mut Self {
74        for entry in entries {
75            self.insert_entry(entry);
76        }
77        self
78    }
79}
80
81impl<P: PluginBridge> WorldInfoFactory<P> for WorldInfo<P> {
82    fn new(registry: Box<ProcessorRegistry<P>>) -> Self {
83        WorldInfo {
84            name: String::new(),
85            entries: Vec::new(),
86            permitted_processors: Vec::new(),
87            processor_registry: registry,
88            error_stack: Vec::new()
89        }
90    }
91    fn set_name(&mut self, name: &str) -> &mut Self {
92        self.name = name.to_string();
93        self
94    }
95    fn insert_entry(&mut self, entry: WorldInfoEntry) -> &mut Self {
96        self.entries.push(entry);
97        self
98    }
99    fn set_permitted_processors(&mut self, processors: Vec<String>) -> &mut Self {
100        self.permitted_processors = processors;
101        self
102    }
103    fn build(&self) -> &WorldInfo::<P> {
104        self
105    }
106}
107
108pub struct WorldInfoEntry {
109    name: String,
110    id: u32,
111    order: u32,
112    nodes: Vec<Box<dyn WorldInfoNode>>,
113    text: String
114}
115
116
117impl WorldInfoEntry {
118    pub fn new(name: String, id: u32, order: u32) -> Self {
119        Self { name, id, order, nodes: Vec::new(), text: String::new() }
120    }
121
122    pub fn evalute(&self) -> Result<String, crate::WorldInfoError> {
123        let mut result = String::new();
124        for node in &self.nodes {
125            match node.content() {
126                Ok(content) => result.push_str(&content),
127                Err(err) => return Err(err)
128            }
129        }
130        Ok(result.into())
131    }
132
133    pub fn name(&self) -> String {
134        self.name.clone()
135    }
136
137    pub fn id(&self) -> u32 {
138        self.id
139    }
140
141    pub fn order(&self) -> u32 {
142        self.order
143    }
144}
145
146pub trait EntryFactory {
147    fn create(name: &str, id: u32, order: u32) -> WorldInfoEntry;
148    fn set_text(&mut self, text: &str) -> &mut WorldInfoEntry;
149    fn parse<P: PluginBridge>(&mut self, registry: &ProcessorRegistry<P>) -> Result<&mut WorldInfoEntry, WorldInfoError>;
150}
151
152impl EntryFactory for WorldInfoEntry {
153    fn create(name: &str, id: u32, order: u32) -> WorldInfoEntry {
154        WorldInfoEntry::new(name.to_string(), id, order)
155    }
156    fn parse<P: PluginBridge>(&mut self, registry: &ProcessorRegistry<P>) -> Result<&mut WorldInfoEntry, WorldInfoError> {
157        println!("Parsing node: {:?}", self.text);
158        match parse_entry_content(&self.text, registry) {
159            Ok(nodes) => self.nodes = nodes,
160            Err(e) => return Err(WorldInfoError::ParserError(e)),
161        }
162        Ok(self)
163    }
164    
165    fn set_text(&mut self, text: &str) -> &mut WorldInfoEntry {
166        self.text = text.to_string();
167        self
168    }
169}
170
171pub trait WorldInfoNode: Debug {
172    fn content(&self) -> Result<String, crate::WorldInfoError>;
173    fn name(&self) -> String;
174    fn cloned(&self) -> Box<dyn WorldInfoNode + '_>;
175}
176
177pub trait WorldInfoProcessor: WorldInfoNode {
178    fn process(&self) -> Result<String, crate::WorldInfoError>;
179}
180
181#[derive(Debug, Clone)]
182struct TextNode {
183    content: String,
184}
185
186impl WorldInfoNode for TextNode {
187    fn content(&self) -> Result<String, crate::WorldInfoError> {
188        Ok(self.content.clone())
189    }
190    
191    fn name(&self) -> String {
192        "text".to_string()
193    }
194    
195    fn cloned(&self) -> Box<dyn WorldInfoNode> {
196        Box::new(self.to_owned())
197    }
198}
199