kotoba_rewrite/rewrite/
matcher.rs1use kotoba_core::ir::*;
4use kotoba_storage::KeyValueStore;
5use kotoba_core::types::*;
6use std::collections::HashMap;
7use std::sync::Arc;
8use tracing::warn;
9
10#[derive(Debug)]
12pub struct RuleMatcher<T: KeyValueStore + 'static> {
13 storage: Arc<T>,
14}
15
16impl<T: KeyValueStore + 'static> RuleMatcher<T> {
17 pub fn new(storage: Arc<T>) -> Self {
18 Self { storage }
19 }
20
21 pub async fn find_matches(&self, graph_key: &str, rule: &RuleIR) -> anyhow::Result<Vec<serde_json::Value>> {
23 warn!("Rule matching not fully implemented yet");
25
26 Ok(vec![])
28 }
29
30 pub async fn save_match(&self, graph_key: &str, rule_name: &str, match_data: &serde_json::Value) -> anyhow::Result<()> {
32 let match_key = format!("match:{}:{}:{}", graph_key, rule_name, chrono::Utc::now().timestamp());
33 let match_bytes = serde_json::to_vec(match_data)?;
34
35 self.storage.put(match_key.as_bytes(), &match_bytes).await?;
36 Ok(())
37 }
38
39 pub async fn load_matches(&self, graph_key: &str, rule_name: &str) -> anyhow::Result<Vec<serde_json::Value>> {
41 let prefix = format!("match:{}:{}:", graph_key, rule_name);
42 let keys = self.storage.scan(prefix.as_bytes()).await?;
43
44 let mut matches = Vec::new();
45 for key_bytes in keys {
46 if let Ok(key_str) = std::str::from_utf8(&key_bytes.0) {
47 if key_str.starts_with(&prefix) {
48 if let Some(match_data) = self.storage.get(&key_bytes.0).await? {
49 if let Ok(match_json) = serde_json::from_slice::<serde_json::Value>(&match_data) {
50 matches.push(match_json);
51 }
52 }
53 }
54 }
55 }
56
57 Ok(matches)
58 }
59}