use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use super::LogStream;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
pub struct LogEntry {
pub id: Uuid,
pub run_id: Uuid,
pub step_id: Uuid,
pub step_name: String,
pub stream: LogStream,
pub line: String,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
pub struct NewLogEntries {
pub run_id: Uuid,
pub step_id: Uuid,
pub step_name: String,
pub stream: LogStream,
pub lines: Vec<String>,
}
#[derive(Debug, Clone, Default)]
pub struct LogFilter {
pub step_id: Option<Uuid>,
pub stream: Option<LogStream>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn log_entry_serde_roundtrip() {
let entry = LogEntry {
id: Uuid::now_v7(),
run_id: Uuid::now_v7(),
step_id: Uuid::now_v7(),
step_name: "build".to_string(),
stream: LogStream::Stdout,
line: "Compiling ironflow v0.1.0".to_string(),
created_at: Utc::now(),
};
let json = serde_json::to_string(&entry).unwrap();
let back: LogEntry = serde_json::from_str(&json).unwrap();
assert_eq!(back.id, entry.id);
assert_eq!(back.stream, LogStream::Stdout);
assert_eq!(back.line, "Compiling ironflow v0.1.0");
}
#[test]
fn log_filter_default_is_empty() {
let filter = LogFilter::default();
assert!(filter.step_id.is_none());
assert!(filter.stream.is_none());
}
#[test]
fn new_log_entries_creation() {
let entries = NewLogEntries {
run_id: Uuid::now_v7(),
step_id: Uuid::now_v7(),
step_name: "deploy".to_string(),
stream: LogStream::Stderr,
lines: vec!["error!".to_string()],
};
assert_eq!(entries.stream, LogStream::Stderr);
assert_eq!(entries.lines.len(), 1);
}
}