1use petgraph::graph::NodeIndex;
2use tracing::info;
3
4use crate::{Graph, GraphEdge, GraphNode, Value};
5
6use super::{GetStoreError, NodeError, NodeWrapper, StoreWrapper, SyncNode};
7
8#[derive(Debug, Clone, Copy)]
10pub struct LogNode(pub NodeIndex);
11
12impl From<LogNode> for NodeIndex {
13 fn from(value: LogNode) -> Self {
14 value.0
15 }
16}
17
18impl NodeWrapper for LogNode {}
19
20impl LogNode {
21 pub fn new(graph: &mut Graph) -> Self {
22 let index = graph.add_node(GraphNode::SyncNode(Box::new(LogWeight)));
23
24 let input = graph.add_node(GraphNode::Store(Value::String(Default::default())));
25 graph.add_edge(input, index, GraphEdge::DataMap(0));
26
27 Self(index)
28 }
29
30 pub fn message(&self, graph: &Graph) -> Result<StoreWrapper, GetStoreError> {
31 self.input_stores(graph)
32 .next()
33 .ok_or(GetStoreError::NoStore)
34 }
35}
36
37struct LogWeight;
38
39impl SyncNode for LogWeight {
40 fn run(&self, inputs: Vec<Value>) -> Result<Vec<Value>, NodeError> {
41 let input = inputs
42 .first()
43 .ok_or(NodeError::InternalError("No input".to_string()))?;
44
45 let value = match input {
46 Value::String(value) => value,
47 _ => return Err(NodeError::ConversionError(input.clone())),
48 };
49
50 info!("{}", value);
51
52 Ok(vec![])
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use tracing_test::traced_test;
59
60 use crate::execution::ExecutionStep;
61
62 use super::*;
63
64 #[test]
65 #[traced_test]
66 fn test_log_weight() {
67 let weight = LogWeight;
68
69 weight
70 .run(vec!["Hello, world!".to_string().into()])
71 .unwrap();
72
73 assert!(logs_contain("Hello, world!"));
74 }
75
76 #[tokio::test]
77 #[traced_test]
78 async fn test_log() {
79 let mut graph = Graph::new();
80 let log = LogNode::new(&mut graph);
81
82 let message = log.message(&graph).unwrap();
83 message.set_value(&mut graph, "Hello, world!".to_string().into());
84
85 let step = ExecutionStep(log.0);
86
87 let _ = step.execute(&mut graph).await.unwrap();
88
89 assert!(logs_contain("Hello, world!"));
90 }
91}