1use crate::grimoire::trie::state::{State, StatusCode};
8use crate::key::Key;
9use crate::query::Query;
10use std::io;
11
12pub struct Agent {
20 query: Query,
22 key: Key,
24 state: Option<Box<State>>,
26}
27
28impl Default for Agent {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl Clone for Agent {
35 fn clone(&self) -> Self {
36 let mut cloned = Agent {
37 query: self.query.clone(),
38 key: self.key.clone(),
39 state: self.state.as_ref().map(|s| Box::new((**s).clone())),
40 };
41
42 let should_update = cloned.state.is_some();
44 if should_update {
45 if let Some(ref state) = cloned.state {
46 let status = state.status_code();
47 match status {
48 StatusCode::ReadyToPredictiveSearch | StatusCode::EndOfPredictiveSearch => {
49 let key_buf = state.key_buf();
51 cloned.key.set_bytes(key_buf);
52 }
53 _ => {
54 }
56 }
57 }
58 }
59
60 cloned
61 }
62}
63
64impl Agent {
65 pub fn new() -> Self {
67 Agent {
68 query: Query::new(),
69 key: Key::new(),
70 state: None,
71 }
72 }
73
74 pub fn query(&self) -> &Query {
76 &self.query
77 }
78
79 pub fn query_mut(&mut self) -> &mut Query {
81 &mut self.query
82 }
83
84 pub fn key(&self) -> &Key {
86 &self.key
87 }
88
89 pub fn key_mut(&mut self) -> &mut Key {
91 &mut self.key
92 }
93
94 pub fn set_query_str(&mut self, s: &str) {
96 if let Some(ref mut state) = self.state {
97 state.reset();
98 }
99 self.query.set_str(s);
100 }
101
102 pub fn set_query_bytes(&mut self, bytes: &[u8]) {
104 if let Some(ref mut state) = self.state {
105 state.reset();
106 }
107 self.query.set_bytes(bytes);
108 }
109
110 pub fn set_query_id(&mut self, key_id: usize) {
112 if let Some(ref mut state) = self.state {
113 state.reset();
114 }
115 self.query.set_id(key_id);
116 }
117
118 pub fn state(&self) -> Option<&State> {
120 self.state.as_deref()
121 }
122
123 pub fn state_mut(&mut self) -> Option<&mut State> {
125 self.state.as_deref_mut()
126 }
127
128 pub fn set_key_str(&mut self, s: &str) {
130 self.key.set_str(s);
131 }
132
133 pub fn set_key_bytes(&mut self, bytes: &[u8]) {
135 self.key.set_bytes(bytes);
136 }
137
138 pub fn set_key_id(&mut self, id: usize) {
140 self.key.set_id(id);
141 }
142
143 pub fn set_key_from_state_buf(&mut self) {
148 if let Some(ref state) = self.state {
149 let buf = state.key_buf();
150 self.key.set_bytes(buf);
154 } else {
155 panic!("Agent must have state to set key from state buffer");
156 }
157 }
158
159 pub fn set_key_from_query(&mut self) {
164 let bytes = self.query.as_bytes();
165 self.key.set_bytes(bytes);
166 }
167
168 pub fn set_key_from_query_prefix(&mut self, length: usize) {
177 let bytes = self.query.as_bytes();
178 assert!(length <= bytes.len(), "Prefix length out of bounds");
179 self.key.set_bytes(&bytes[..length]);
180 }
181
182 pub fn has_state(&self) -> bool {
184 self.state.is_some()
185 }
186
187 pub fn init_state(&mut self) -> io::Result<()> {
193 if self.state.is_some() {
194 return Err(io::Error::new(
195 io::ErrorKind::AlreadyExists,
196 "State already initialized",
197 ));
198 }
199 self.state = Some(Box::new(State::new()));
200 Ok(())
201 }
202
203 pub fn clear(&mut self) {
205 *self = Agent::new();
206 }
207
208 pub fn swap(&mut self, other: &mut Agent) {
210 std::mem::swap(self, other);
211 }
212}
213
214#[allow(dead_code)]
219fn update_agent_after_copying_state(state: &State, agent: &mut Agent) {
220 match state.status_code() {
221 StatusCode::ReadyToPredictiveSearch | StatusCode::EndOfPredictiveSearch => {
222 let key_buf = state.key_buf();
224 agent.key.set_bytes(key_buf);
225 }
226 _ => {
227 }
229 }
230}
231
232#[cfg(test)]
233mod tests {
234 use super::*;
235
236 #[test]
237 fn test_agent_new() {
238 let agent = Agent::new();
239 assert_eq!(agent.query().length(), 0);
240 assert_eq!(agent.key().length(), 0);
241 assert!(!agent.has_state());
242 }
243
244 #[test]
245 fn test_agent_default() {
246 let agent = Agent::default();
247 assert_eq!(agent.query().length(), 0);
248 }
249
250 #[test]
251 fn test_agent_set_query_str() {
252 let mut agent = Agent::new();
253 agent.set_query_str("hello");
254
255 assert_eq!(agent.query().as_str(), "hello");
256 assert_eq!(agent.query().length(), 5);
257 }
258
259 #[test]
260 fn test_agent_set_query_bytes() {
261 let mut agent = Agent::new();
262 agent.set_query_bytes(b"world");
263
264 assert_eq!(agent.query().as_bytes(), b"world");
265 assert_eq!(agent.query().length(), 5);
266 }
267
268 #[test]
269 fn test_agent_set_query_id() {
270 let mut agent = Agent::new();
271 agent.set_query_id(42);
272
273 assert_eq!(agent.query().id(), 42);
274 }
275
276 #[test]
277 fn test_agent_set_key_str() {
278 let mut agent = Agent::new();
279 agent.set_key_str("test");
280
281 assert_eq!(agent.key().as_str(), "test");
282 }
283
284 #[test]
285 fn test_agent_set_key_id() {
286 let mut agent = Agent::new();
287 agent.set_key_id(100);
288
289 assert_eq!(agent.key().id(), 100);
290 }
291
292 #[test]
293 fn test_agent_init_state() {
294 let mut agent = Agent::new();
295 assert!(!agent.has_state());
296
297 agent.init_state().unwrap();
298 assert!(agent.has_state());
299 }
300
301 #[test]
302 fn test_agent_init_state_already_exists() {
303 let mut agent = Agent::new();
304 agent.init_state().unwrap();
305
306 let result = agent.init_state();
307 assert!(result.is_err());
308 }
309
310 #[test]
311 fn test_agent_state_reset_on_set_query() {
312 let mut agent = Agent::new();
313 agent.init_state().unwrap();
314
315 {
316 let state = agent.state_mut().unwrap();
317 state.set_status_code(StatusCode::EndOfPredictiveSearch);
318 }
319
320 agent.set_query_str("new query");
322
323 let state = agent.state().unwrap();
324 assert_eq!(state.status_code(), StatusCode::ReadyToAll);
325 }
326
327 #[test]
328 fn test_agent_clear() {
329 let mut agent = Agent::new();
330 agent.set_query_str("test");
331 agent.set_key_id(10);
332 agent.init_state().unwrap();
333
334 agent.clear();
335
336 assert_eq!(agent.query().length(), 0);
337 assert_eq!(agent.key().length(), 0);
338 assert!(!agent.has_state());
339 }
340
341 #[test]
342 fn test_agent_swap() {
343 let s1 = "query1";
344 let s2 = "query2";
345
346 let mut a1 = Agent::new();
347 a1.set_query_str(s1);
348 a1.set_key_id(1);
349
350 let mut a2 = Agent::new();
351 a2.set_query_str(s2);
352 a2.set_key_id(2);
353 a2.init_state().unwrap();
354
355 a1.swap(&mut a2);
356
357 assert_eq!(a1.query().as_str(), "query2");
358 assert_eq!(a1.key().id(), 2);
359 assert!(a1.has_state());
360
361 assert_eq!(a2.query().as_str(), "query1");
362 assert_eq!(a2.key().id(), 1);
363 assert!(!a2.has_state());
364 }
365
366 #[test]
367 fn test_agent_clone() {
368 let mut agent = Agent::new();
369 agent.set_query_str("original");
370 agent.set_key_id(42);
371 agent.init_state().unwrap();
372
373 let cloned = agent.clone();
374
375 assert_eq!(cloned.query().as_str(), "original");
376 assert_eq!(cloned.key().id(), 42);
377 assert!(cloned.has_state());
378 }
379
380 #[test]
381 fn test_agent_query_mut() {
382 let mut agent = Agent::new();
383 agent.query_mut().set_str("mutable");
384
385 assert_eq!(agent.query().as_str(), "mutable");
386 }
387
388 #[test]
389 fn test_agent_key_mut() {
390 let mut agent = Agent::new();
391 agent.key_mut().set_id(99);
392
393 assert_eq!(agent.key().id(), 99);
394 }
395}