diff --git a/Cargo.lock b/Cargo.lock index 135870a..1d9fc29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -841,6 +841,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", + "smallvec", "tempfile", "thiserror", "timer", @@ -1017,9 +1018,12 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "socket2" diff --git a/Cargo.toml b/Cargo.toml index 1f34b57..5187a73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ tokio = { version = "1.40.0", features = ["full", "tracing"] } tokio-util = { version = "0.7.12", features = ["codec"] } tracing = "0.1.40" tracing-subscriber = "0.3.18" +smallvec = { version = "1.15.1", features = ["serde"] } [build-dependencies] clap = { version = "4.5.4", features = ["derive"] } diff --git a/src/concepts/filter.rs b/src/concepts/filter.rs index 8f13413..9c3b34d 100644 --- a/src/concepts/filter.rs +++ b/src/concepts/filter.rs @@ -223,7 +223,7 @@ impl Filter { } } else { info!("{}: match []", self); - return Some(vec![".".to_string()]); + return Some(smallvec::smallvec![".".to_string()]); } } } @@ -643,7 +643,7 @@ pub mod tests { filter.actions.insert(name.clone(), ok_action()); filter.regex.push("insert here$".to_string()); assert!(filter.setup(&name, &name, &patterns).is_ok()); - assert_eq!(filter.get_match("insert b here"), Some(vec!("b".into()))); + assert_eq!(filter.get_match("insert b here"), Some(smallvec::smallvec!("b".into()))); assert_eq!(filter.get_match("insert a here"), None); assert_eq!(filter.get_match("youpi b youpi"), None); assert_eq!(filter.get_match("insert here"), None); @@ -651,7 +651,7 @@ pub mod tests { // Ok assert_eq!( filter.get_match_from_patterns(BTreeMap::from([(pattern.clone(), "b".into())])), - Ok(vec!("b".into())) + Ok(smallvec::smallvec!("b".into())) ); // Doesn't match assert!(filter @@ -684,7 +684,7 @@ pub mod tests { assert!(filter.setup(&name, &name, &patterns).is_ok()); assert_eq!( filter.get_match("insert b here and bouboubou there"), - Some(vec!("bouboubou".into(), "b".into())) + Some(smallvec::smallvec!("bouboubou".into(), "b".into())) ); assert_eq!(filter.get_match("insert a here and bouboubou there"), None); assert_eq!(filter.get_match("insert b here and boubou there"), None); @@ -696,7 +696,7 @@ pub mod tests { (boubou.clone(), "bou".into()), ])), // Reordered by pattern name - Ok(vec!("bou".into(), "b".into())) + Ok(smallvec::smallvec!("bou".into(), "b".into())) ); // Doesn't match assert!(filter @@ -737,9 +737,9 @@ pub mod tests { filter.regex.push("also add there".to_string()); assert!(filter.setup(&name, &name, &patterns).is_ok()); assert_eq!(filter.get_match("insert a here"), None); - assert_eq!(filter.get_match("insert b here"), Some(vec!("b".into()))); + assert_eq!(filter.get_match("insert b here"), Some(smallvec::smallvec!("b".into()))); assert_eq!(filter.get_match("also add a there"), None); - assert_eq!(filter.get_match("also add b there"), Some(vec!("b".into()))); + assert_eq!(filter.get_match("also add b there"), Some(smallvec::smallvec!("b".into()))); // multiple regexes with same patterns filter = Filter::default(); @@ -753,11 +753,11 @@ pub mod tests { assert!(filter.setup(&name, &name, &patterns).is_ok()); assert_eq!( filter.get_match("insert b here and bouboubou there"), - Some(vec!("bouboubou".into(), "b".into())) + Some(smallvec::smallvec!("bouboubou".into(), "b".into())) ); assert_eq!( filter.get_match("also add bouboubou here and b there"), - Some(vec!("bouboubou".into(), "b".into())) + Some(smallvec::smallvec!("bouboubou".into(), "b".into())) ); assert_eq!(filter.get_match("insert a here and bouboubou there"), None); assert_eq!( diff --git a/src/concepts/mod.rs b/src/concepts/mod.rs index a163286..4d6e37c 100644 --- a/src/concepts/mod.rs +++ b/src/concepts/mod.rs @@ -11,12 +11,13 @@ pub use filter::Filter; use parse_duration::parse_duration; pub use pattern::Pattern; use serde::{Deserialize, Serialize}; +use smallvec::SmallVec; pub use stream::Stream; use chrono::{DateTime, Local}; pub type Time = DateTime; -pub type Match = Vec; +pub type Match = SmallVec<[String; 1]>; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub struct MatchTime { diff --git a/src/daemon/filter/tests.rs b/src/daemon/filter/tests.rs index cc9947b..ab55c3a 100644 --- a/src/daemon/filter/tests.rs +++ b/src/daemon/filter/tests.rs @@ -124,7 +124,7 @@ async fn three_matches_then_action_then_delayed_action() { bed.assert_empty_trees(); // First match - let one = vec!["one".to_string()]; + let one = smallvec::smallvec!["one".to_string()]; assert_eq!(bed.manager.handle_line("test one", now), React::Match); { let state = bed.manager.state.lock().unwrap(); @@ -294,7 +294,7 @@ async fn one_match_one_delayed_action() { bed.assert_empty_trees(); // Match - let one = vec!["one".to_string()]; + let one = smallvec::smallvec!["one".to_string()]; assert_eq!(bed.manager.handle_line("test one", now), React::Exec); { let state = bed.manager.state.lock().unwrap(); @@ -358,12 +358,12 @@ async fn one_db_match_one_runtime_match_one_action() { // Pre-add match let now = Local::now(); - let one = vec!["one".to_string()]; + let one = smallvec::smallvec!["one".to_string()]; let now1s = now - TimeDelta::seconds(1); db.set_loaded_db(HashMap::from([( filter_ordered_times_db_name(filter), - HashMap::from([(now1s.to_rfc3339().into(), one.clone().into())]), + HashMap::from([(now1s.to_rfc3339().into(), one.to_vec().into())]), )])); // Finish setup @@ -472,7 +472,7 @@ async fn trigger_unmatched_pattern() { ); let now = Local::now(); - let one = vec!["one".to_string()]; + let one = smallvec::smallvec!["one".to_string()]; let bed = bed.part2(filter, now, None).await; bed.manager @@ -481,7 +481,7 @@ async fn trigger_unmatched_pattern() { bed.az_patterns .values() .cloned() - .map(|pattern| (pattern, one[0].clone())) + .map(|pattern| (pattern, "one".to_string())) .collect(), now, ) @@ -547,12 +547,12 @@ async fn trigger_matched_pattern() { let now = Local::now(); let now1s = now - TimeDelta::milliseconds(10); - let one = vec!["one".to_string()]; + let one = smallvec::smallvec!["one".to_string()]; let mut db = TempDatabase::default().await; db.set_loaded_db(HashMap::from([( filter_ordered_times_db_name(filter), - HashMap::from([(now1s.to_rfc3339().into(), one.clone().into())]), + HashMap::from([(now1s.to_rfc3339().into(), one.to_vec().into())]), )])); let bed = bed.part2(filter, now, Some(db)).await; @@ -562,7 +562,7 @@ async fn trigger_matched_pattern() { bed.az_patterns .values() .cloned() - .map(|pattern| (pattern, one[0].clone())) + .map(|pattern| (pattern, "one".to_string())) .collect(), now, ) diff --git a/src/treedb/helpers.rs b/src/treedb/helpers.rs index 7833957..94d2ad3 100644 --- a/src/treedb/helpers.rs +++ b/src/treedb/helpers.rs @@ -99,10 +99,10 @@ mod tests { #[test] fn test_to_match() { - assert_eq!(to_match(&([""].into())), Ok(vec!["".into()])); + assert_eq!(to_match(&([""].into())), Ok(smallvec::smallvec!["".into()])); assert_eq!( to_match(&(["plip", "ploup"].into())), - Ok(vec!["plip".into(), "ploup".into()]) + Ok(smallvec::smallvec!["plip".into(), "ploup".into()]) ); assert!(to_match(&[Value::from("plip"), Value::from(10)].into()).is_err()); @@ -153,7 +153,7 @@ mod tests { .into_iter() ))), Ok(MatchTime { - m: vec!["plip".into(), "ploup".into()], + m: smallvec::smallvec!["plip".into(), "ploup".into()], t: Local.timestamp_millis_opt(12345678).unwrap(), }) ); diff --git a/src/treedb/mod.rs b/src/treedb/mod.rs index 8809169..cacb673 100644 --- a/src/treedb/mod.rs +++ b/src/treedb/mod.rs @@ -551,49 +551,49 @@ mod tests { let valid = now + TimeDelta::seconds(2); - let ip127 = vec!["127.0.0.1".to_string()]; - let ip1 = vec!["1.1.1.1".to_string()]; + let ip127 = smallvec::smallvec!["127.0.0.1".to_string()]; + let ip1 = smallvec::smallvec!["1.1.1.1".to_string()]; let entries = [ Entry { tree: "time-match".into(), key: now_ms.clone().into(), - value: Some(ip127.clone().into()), + value: Some(ip127.to_vec().into()), expiry: valid, }, Entry { tree: "time-match".into(), key: now2_ms.clone().into(), - value: Some(ip127.clone().into()), + value: Some(ip127.to_vec().into()), expiry: valid, }, Entry { tree: "time-match".into(), key: now3_ms.clone().into(), - value: Some(ip127.clone().into()), + value: Some(ip127.to_vec().into()), expiry: valid, }, Entry { tree: "time-match".into(), key: now2_ms.clone().into(), - value: Some(ip127.clone().into()), + value: Some(ip127.to_vec().into()), expiry: valid, }, Entry { tree: "match-timeset".into(), - key: ip127.clone().into(), + key: ip127.to_vec().into(), value: Some([Value::String(now_ms)].into()), expiry: valid, }, Entry { tree: "match-timeset".into(), - key: ip1.clone().into(), + key: ip1.to_vec().into(), value: Some([Value::String(now2_ms.clone())].into()), expiry: valid, }, Entry { tree: "match-timeset".into(), - key: ip1.clone().into(), + key: ip1.to_vec().into(), value: Some([Value::String(now2_ms.clone()), now3_ms.into()].into()), expiry: valid, },