use crate::ast::Value;
fn log_at(level: crate::library::support::audit::LogLevel, fn_name: &str, value: &Value) {
let msg = format!("{fn_name}: {}", value.to_display_string());
crate::library::support::audit::log(level, &msg);
}
#[crate::polydat_node(category = Diagnostic, purity = SideChannel(LogBuffer))]
fn log_debug(value: Value) -> Value {
log_at(crate::library::support::audit::LogLevel::Debug, "log_debug", &value);
value
}
#[crate::polydat_node(category = Diagnostic, purity = SideChannel(LogBuffer))]
fn log_info(value: Value) -> Value {
log_at(crate::library::support::audit::LogLevel::Info, "log_info", &value);
value
}
#[crate::polydat_node(category = Diagnostic, purity = SideChannel(LogBuffer))]
fn log_warn(value: Value) -> Value {
log_at(crate::library::support::audit::LogLevel::Warn, "log_warn", &value);
value
}
#[crate::polydat_node(category = Diagnostic, purity = SideChannel(LogBuffer))]
fn log_error(value: Value) -> Value {
log_at(crate::library::support::audit::LogLevel::Error, "log_error", &value);
value
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::{PolydatNode, PortType, Slot};
#[test]
fn log_debug_passthrough() {
let node = LogDebug::new(PortType::Str);
let mut out = [Value::None];
node.eval(&[Value::Str("hello".into())], &mut out);
assert_eq!(out[0].as_str(), "hello");
}
#[test]
fn log_info_passthrough() {
let node = LogInfo::new(PortType::Bool);
let mut out = [Value::None];
node.eval(&[Value::Bool(true)], &mut out);
assert!(out[0].as_bool());
}
#[test]
fn log_warn_passthrough() {
let node = LogWarn::new(PortType::U64);
let mut out = [Value::None];
node.eval(&[Value::U64(42)], &mut out);
assert_eq!(out[0].as_u64(), 42);
}
#[test]
fn log_error_passthrough() {
let node = LogError::new(PortType::F64);
let mut out = [Value::None];
node.eval(&[Value::F64(1.5)], &mut out);
assert_eq!(out[0].as_f64(), 1.5);
}
#[test]
fn log_node_meta_has_one_input_one_output() {
let node = LogInfo::new(PortType::Str);
assert_eq!(node.meta().ins.len(), 1);
assert_eq!(node.meta().outs.len(), 1);
assert_eq!(node.meta().name, "log_info");
}
#[test]
fn log_info_meta_tracks_constructor_port_type() {
let node = LogInfo::new(PortType::Bool);
assert_eq!(node.meta().outs[0].typ, PortType::Bool);
if let Slot::Wire(p) = &node.meta().ins[0] {
assert_eq!(p.typ, PortType::Bool);
} else {
panic!("expected Slot::Wire");
}
}
#[test]
fn log_purity_is_side_channel() {
use crate::ast::{Purity, SideChannelSink};
let node = LogInfo::new(PortType::U64);
let p = node.purity();
assert!(matches!(p, Purity::SideChannel { sink: SideChannelSink::LogBuffer }));
}
}