kotoba_rewrite/rewrite/
matcher.rs

1//! ルールマッチング
2
3use kotoba_core::ir::*;
4use kotoba_storage::KeyValueStore;
5use kotoba_core::types::*;
6use std::collections::HashMap;
7use std::sync::Arc;
8use tracing::warn;
9
10/// ルールマッチャー with KeyValueStore backend
11#[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    /// グラフに対してルールをマッチング (KeyValueStoreベース)
22    pub async fn find_matches(&self, graph_key: &str, rule: &RuleIR) -> anyhow::Result<Vec<serde_json::Value>> {
23        // TODO: Implement rule matching using KeyValueStore
24        warn!("Rule matching not fully implemented yet");
25
26        // For now, return empty matches
27        Ok(vec![])
28    }
29
30    /// マッチング結果を保存
31    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    /// マッチング結果を読み込み
40    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}