1use std::path::PathBuf;
8
9use crate::graph::{CellId, CellInfo, Dependency, SourceSpan};
10
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16pub struct CellData {
17 pub id: usize,
19 pub name: String,
21 pub display_name: String,
23 pub param_names: Vec<String>,
25 pub param_types: Vec<String>,
27 pub param_is_ref: Vec<bool>,
29 pub param_is_mut: Vec<bool>,
31 pub return_type: String,
33 pub doc_comment: Option<String>,
35 pub source_code: String,
37 pub source_file: PathBuf,
39 pub span: (usize, usize, usize, usize),
41}
42
43impl From<CellInfo> for CellData {
44 fn from(info: CellInfo) -> Self {
45 Self {
46 id: info.id.as_usize(),
47 name: info.name,
48 display_name: info.display_name,
49 param_names: info
50 .dependencies
51 .iter()
52 .map(|d| d.param_name.clone())
53 .collect(),
54 param_types: info
55 .dependencies
56 .iter()
57 .map(|d| d.param_type.clone())
58 .collect(),
59 param_is_ref: info.dependencies.iter().map(|d| d.is_ref).collect(),
60 param_is_mut: info.dependencies.iter().map(|d| d.is_mut).collect(),
61 return_type: info.return_type,
62 doc_comment: info.doc_comment,
63 source_code: info.source_code,
64 source_file: info.source_file,
65 span: (
66 info.span.start_line,
67 info.span.start_col,
68 info.span.end_line,
69 info.span.end_col,
70 ),
71 }
72 }
73}
74
75impl From<CellData> for CellInfo {
76 fn from(data: CellData) -> Self {
77 let dependencies: Vec<Dependency> = data
78 .param_names
79 .into_iter()
80 .zip(data.param_types)
81 .zip(data.param_is_ref)
82 .zip(data.param_is_mut)
83 .map(|(((name, ty), is_ref), is_mut)| Dependency {
84 param_name: name,
85 param_type: ty,
86 is_ref,
87 is_mut,
88 })
89 .collect();
90
91 Self {
92 id: CellId::new(data.id),
93 name: data.name,
94 display_name: data.display_name,
95 dependencies,
96 return_type: data.return_type,
97 doc_comment: data.doc_comment,
98 source_code: data.source_code,
99 source_file: data.source_file,
100 span: SourceSpan {
101 start_line: data.span.0,
102 start_col: data.span.1,
103 end_line: data.span.2,
104 end_col: data.span.3,
105 },
106 }
107 }
108}
109
110#[derive(Debug, Clone, PartialEq, Eq, Hash)]
115pub struct CompiledCellData {
116 pub cell_id: usize,
118
119 pub name: String,
121
122 pub dylib_path: PathBuf,
124
125 pub entry_symbol: String,
127
128 pub source_hash: u64,
130
131 pub deps_hash: u64,
133
134 pub compile_time_ms: u64,
136}
137
138impl From<crate::compile::CompiledCell> for CompiledCellData {
139 fn from(compiled: crate::compile::CompiledCell) -> Self {
140 Self {
141 cell_id: compiled.cell_id.as_usize(),
142 name: compiled.name,
143 dylib_path: compiled.dylib_path,
144 entry_symbol: compiled.entry_symbol,
145 source_hash: compiled.source_hash,
146 deps_hash: compiled.deps_hash,
147 compile_time_ms: compiled.compile_time_ms,
148 }
149 }
150}
151
152impl CompiledCellData {
153 pub fn to_compiled_cell(&self) -> crate::compile::CompiledCell {
155 crate::compile::CompiledCell {
156 cell_id: CellId::new(self.cell_id),
157 name: self.name.clone(),
158 dylib_path: self.dylib_path.clone(),
159 entry_symbol: self.entry_symbol.clone(),
160 source_hash: self.source_hash,
161 deps_hash: self.deps_hash,
162 compile_time_ms: self.compile_time_ms,
163 }
164 }
165}
166
167#[derive(Debug, Clone, PartialEq, Eq, Hash)]
169pub enum CompilationStatus {
170 Success(CompiledCellData),
172 Cached(CompiledCellData),
174 Failed(String),
176}
177
178impl CompilationStatus {
179 pub fn compiled(&self) -> Option<&CompiledCellData> {
181 match self {
182 Self::Success(data) | Self::Cached(data) => Some(data),
183 Self::Failed(_) => None,
184 }
185 }
186
187 pub fn is_success(&self) -> bool {
189 matches!(self, Self::Success(_) | Self::Cached(_))
190 }
191}
192
193#[derive(Debug, Clone, PartialEq, Eq, Hash)]
199pub struct CellOutputData {
200 pub cell_id: usize,
202
203 pub bytes: Vec<u8>,
205
206 pub type_hash: u64,
208
209 pub type_name: String,
211
212 pub inputs_hash: u64,
215
216 pub execution_time_ms: u64,
218}
219
220impl CellOutputData {
221 pub fn from_boxed(
223 cell_id: usize,
224 boxed: &crate::state::BoxedOutput,
225 inputs_hash: u64,
226 execution_time_ms: u64,
227 ) -> Self {
228 Self {
229 cell_id,
230 bytes: boxed.bytes().to_vec(),
231 type_hash: boxed.type_hash(),
232 type_name: boxed.type_name().to_string(),
233 inputs_hash,
234 execution_time_ms,
235 }
236 }
237
238 pub fn to_boxed(&self) -> crate::state::BoxedOutput {
240 crate::state::BoxedOutput::from_raw_with_type(
241 self.bytes.clone(),
242 self.type_hash,
243 self.type_name.clone(),
244 )
245 }
246
247 pub fn is_valid_for(&self, inputs_hash: u64) -> bool {
249 self.inputs_hash == inputs_hash
250 }
251}
252
253#[derive(Debug, Clone, PartialEq, Eq, Hash)]
255pub enum ExecutionStatus {
256 Pending,
258 Running,
260 Success(CellOutputData),
262 Failed(String),
264}
265
266impl ExecutionStatus {
267 pub fn output(&self) -> Option<&CellOutputData> {
269 match self {
270 Self::Success(data) => Some(data),
271 _ => None,
272 }
273 }
274
275 pub fn is_success(&self) -> bool {
277 matches!(self, Self::Success(_))
278 }
279
280 pub fn is_failed(&self) -> bool {
282 matches!(self, Self::Failed(_))
283 }
284}
285
286#[derive(Debug, Clone, PartialEq, Eq, Hash)]
292pub struct GraphAnalysis {
293 pub execution_order: Vec<usize>,
295
296 pub parallel_levels: Vec<Vec<usize>>,
298}
299
300impl GraphAnalysis {
301 pub fn empty() -> Self {
303 Self {
304 execution_order: Vec::new(),
305 parallel_levels: Vec::new(),
306 }
307 }
308
309 pub fn is_empty(&self) -> bool {
311 self.execution_order.is_empty()
312 }
313}
314
315#[cfg(test)]
316mod tests {
317 use super::*;
318
319 #[test]
320 fn test_cell_data_conversion() {
321 let info = CellInfo {
322 id: CellId::new(0),
323 name: "test".to_string(),
324 display_name: "Test Cell".to_string(),
325 dependencies: vec![
326 Dependency {
327 param_name: "x".to_string(),
328 param_type: "i32".to_string(),
329 is_ref: true,
330 is_mut: false,
331 },
332 Dependency {
333 param_name: "y".to_string(),
334 param_type: "Vec<u8>".to_string(),
335 is_ref: true,
336 is_mut: true, },
338 ],
339 return_type: "i32".to_string(),
340 doc_comment: Some("Test cell".to_string()),
341 source_code: "{ 42 }".to_string(),
342 source_file: PathBuf::from("test.rs"),
343 span: SourceSpan {
344 start_line: 1,
345 start_col: 0,
346 end_line: 1,
347 end_col: 10,
348 },
349 };
350
351 let data: CellData = info.clone().into();
353 assert_eq!(data.name, "test");
354 assert_eq!(data.display_name, "Test Cell");
355 assert_eq!(data.param_names, vec!["x", "y"]);
356 assert_eq!(data.param_types, vec!["i32", "Vec<u8>"]);
357 assert_eq!(data.param_is_ref, vec![true, true]);
358 assert_eq!(data.param_is_mut, vec![false, true]);
359
360 let back: CellInfo = data.into();
362 assert_eq!(back.name, "test");
363 assert_eq!(back.dependencies.len(), 2);
364 assert_eq!(back.dependencies[0].param_name, "x");
365 assert!(back.dependencies[0].is_ref);
366 assert!(!back.dependencies[0].is_mut);
367 assert_eq!(back.dependencies[1].param_name, "y");
368 assert!(back.dependencies[1].is_ref);
369 assert!(back.dependencies[1].is_mut); }
371
372 #[test]
373 fn test_compiled_cell_data_conversion() {
374 use crate::compile::CompiledCell;
375
376 let compiled = CompiledCell {
377 cell_id: CellId::new(0),
378 name: "test_cell".to_string(),
379 dylib_path: PathBuf::from("/path/to/cell.so"),
380 entry_symbol: "venus_cell_test_cell".to_string(),
381 source_hash: 12345,
382 deps_hash: 67890,
383 compile_time_ms: 100,
384 };
385
386 let data: CompiledCellData = compiled.clone().into();
388 assert_eq!(data.cell_id, 0);
389 assert_eq!(data.name, "test_cell");
390 assert_eq!(data.dylib_path, PathBuf::from("/path/to/cell.so"));
391 assert_eq!(data.entry_symbol, "venus_cell_test_cell");
392 assert_eq!(data.source_hash, 12345);
393 assert_eq!(data.deps_hash, 67890);
394
395 let back = data.to_compiled_cell();
397 assert_eq!(back.cell_id.as_usize(), 0);
398 assert_eq!(back.name, "test_cell");
399 }
400
401 #[test]
402 fn test_compilation_status() {
403 let data = CompiledCellData {
404 cell_id: 0,
405 name: "test".to_string(),
406 dylib_path: PathBuf::from("/test.so"),
407 entry_symbol: "venus_cell_test".to_string(),
408 source_hash: 1,
409 deps_hash: 2,
410 compile_time_ms: 50,
411 };
412
413 let success = CompilationStatus::Success(data.clone());
414 assert!(success.is_success());
415 assert!(success.compiled().is_some());
416
417 let cached = CompilationStatus::Cached(data);
418 assert!(cached.is_success());
419 assert!(cached.compiled().is_some());
420
421 let failed = CompilationStatus::Failed("error".to_string());
422 assert!(!failed.is_success());
423 assert!(failed.compiled().is_none());
424 }
425}