Skip to main content

fukurow_core/
model.rs

1//! Graph data models for JSON-LD reasoning
2
3use serde::{Deserialize, Serialize};
4// Sophia API imports removed - using simple string-based representation
5use std::collections::HashMap;
6use std::sync::{Arc, RwLock};
7use lazy_static::lazy_static;
8
9/// Global string interning pool for memory optimization
10lazy_static! {
11    static ref STRING_POOL: Arc<RwLock<HashMap<String, Arc<String>>>> = Arc::new(RwLock::new(HashMap::new()));
12}
13
14/// Interned string that reuses memory for identical strings
15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16pub struct InternedString(Arc<String>);
17
18impl InternedString {
19    /// Create a new interned string, reusing existing instances when possible
20    pub fn new<S: Into<String>>(s: S) -> Self {
21        let string = s.into();
22        let mut pool = STRING_POOL.write().unwrap();
23
24        if let Some(interned) = pool.get(&string) {
25            InternedString(Arc::clone(interned))
26        } else {
27            let interned = Arc::new(string.clone());
28            pool.insert(string, Arc::clone(&interned));
29            InternedString(interned)
30        }
31    }
32
33    /// Get the string slice
34    pub fn as_str(&self) -> &str {
35        &self.0
36    }
37
38    /// Get the length
39    pub fn len(&self) -> usize {
40        self.0.len()
41    }
42
43    /// Check if empty
44    pub fn is_empty(&self) -> bool {
45        self.0.is_empty()
46    }
47}
48
49impl From<String> for InternedString {
50    fn from(s: String) -> Self {
51        InternedString::new(s)
52    }
53}
54
55impl From<&str> for InternedString {
56    fn from(s: &str) -> Self {
57        InternedString::new(s)
58    }
59}
60
61impl From<&String> for InternedString {
62    fn from(s: &String) -> Self {
63        InternedString::new(s.clone())
64    }
65}
66
67impl std::fmt::Display for InternedString {
68    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69        write!(f, "{}", self.0)
70    }
71}
72
73impl AsRef<str> for InternedString {
74    fn as_ref(&self) -> &str {
75        self.as_str()
76    }
77}
78
79/// RDF Triple representation
80#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
81pub struct Triple {
82    pub subject: String,
83    pub predicate: String,
84    pub object: String,
85}
86
87/// Memory-optimized RDF Triple using interned strings
88#[derive(Debug, Clone, PartialEq, Eq, Hash)]
89pub struct InternedTriple {
90    pub subject: InternedString,
91    pub predicate: InternedString,
92    pub object: InternedString,
93}
94
95impl InternedTriple {
96    /// Create a new interned triple
97    pub fn new<S: Into<InternedString>, P: Into<InternedString>, O: Into<InternedString>>(
98        subject: S,
99        predicate: P,
100        object: O,
101    ) -> Self {
102        InternedTriple {
103            subject: subject.into(),
104            predicate: predicate.into(),
105            object: object.into(),
106        }
107    }
108
109    /// Convert to regular Triple
110    pub fn to_triple(&self) -> Triple {
111        Triple {
112            subject: self.subject.as_str().to_string(),
113            predicate: self.predicate.as_str().to_string(),
114            object: self.object.as_str().to_string(),
115        }
116    }
117
118    /// Convert from regular Triple
119    pub fn from_triple(triple: &Triple) -> Self {
120        InternedTriple::new(
121            InternedString::from(&triple.subject),
122            InternedString::from(&triple.predicate),
123            InternedString::from(&triple.object),
124        )
125    }
126}
127
128/// JSON-LD Document with context
129#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct JsonLdDocument {
131    #[serde(rename = "@context")]
132    pub context: serde_json::Value,
133    #[serde(rename = "@graph", skip_serializing_if = "Option::is_none")]
134    pub graph: Option<Vec<serde_json::Value>>,
135    #[serde(flatten)]
136    pub data: HashMap<String, serde_json::Value>,
137}
138
139/// Named Graph for organizing triples
140#[derive(Debug, Clone, Default)]
141pub struct NamedGraph {
142    pub name: String,
143    pub triples: Vec<Triple>,
144}
145
146/// Event types in cyber security domain
147#[derive(Debug, Clone, Serialize, Deserialize)]
148#[serde(tag = "type", content = "data")]
149pub enum CyberEvent {
150    NetworkConnection {
151        source_ip: String,
152        dest_ip: String,
153        port: u16,
154        protocol: String,
155        timestamp: i64,
156    },
157    ProcessExecution {
158        process_id: u32,
159        parent_process_id: Option<u32>,
160        command_line: String,
161        user: String,
162        timestamp: i64,
163    },
164    FileAccess {
165        file_path: String,
166        access_type: String,
167        user: String,
168        process_id: u32,
169        timestamp: i64,
170    },
171    UserLogin {
172        user: String,
173        source_ip: String,
174        success: bool,
175        timestamp: i64,
176    },
177}
178
179/// Security actions that can be proposed by the reasoner
180#[derive(Debug, Clone, Serialize, Deserialize)]
181#[serde(tag = "action_type", content = "parameters")]
182pub enum SecurityAction {
183    IsolateHost { host_ip: String, reason: String },
184    BlockConnection { source_ip: String, dest_ip: String, reason: String },
185    TerminateProcess { process_id: u32, reason: String },
186    RevokePrivileges { user: String, privilege: String, reason: String },
187    Alert { severity: String, message: String, details: serde_json::Value },
188}
189
190/// Inference rule for pattern matching
191#[derive(Debug, Clone, Serialize, Deserialize)]
192pub struct InferenceRule {
193    pub name: String,
194    pub description: String,
195    pub conditions: Vec<Triple>,
196    pub actions: Vec<SecurityAction>,
197}