Skip to main content

ironflow_store/entities/
log_stream.rs

1//! Output stream classification for run/step log lines.
2
3use serde::{Deserialize, Serialize};
4
5/// Output stream for a log line.
6///
7/// # Examples
8///
9/// ```
10/// use ironflow_store::entities::LogStream;
11///
12/// let stream: LogStream = "stdout".parse().unwrap();
13/// assert_eq!(stream.as_str(), "stdout");
14/// ```
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
16#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
17#[serde(rename_all = "snake_case")]
18pub enum LogStream {
19    /// Standard output.
20    Stdout,
21    /// Standard error.
22    Stderr,
23    /// System-level messages (e.g. step start/stop notifications).
24    System,
25}
26
27impl LogStream {
28    /// Returns the wire-format string for this stream.
29    pub fn as_str(&self) -> &'static str {
30        match self {
31            Self::Stdout => "stdout",
32            Self::Stderr => "stderr",
33            Self::System => "system",
34        }
35    }
36}
37
38impl std::fmt::Display for LogStream {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        f.write_str(self.as_str())
41    }
42}
43
44impl std::str::FromStr for LogStream {
45    type Err = String;
46
47    fn from_str(s: &str) -> Result<Self, Self::Err> {
48        match s {
49            "stdout" => Ok(Self::Stdout),
50            "stderr" => Ok(Self::Stderr),
51            "system" => Ok(Self::System),
52            _ => Err(format!("unknown log stream: {s}")),
53        }
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn serde_roundtrip() {
63        let stream = LogStream::Stdout;
64        let json = serde_json::to_string(&stream).unwrap();
65        assert_eq!(json, r#""stdout""#);
66        let back: LogStream = serde_json::from_str(&json).unwrap();
67        assert_eq!(back, LogStream::Stdout);
68    }
69
70    #[test]
71    fn from_str_all_variants() {
72        assert_eq!("stdout".parse::<LogStream>().unwrap(), LogStream::Stdout);
73        assert_eq!("stderr".parse::<LogStream>().unwrap(), LogStream::Stderr);
74        assert_eq!("system".parse::<LogStream>().unwrap(), LogStream::System);
75    }
76
77    #[test]
78    fn from_str_unknown_errors() {
79        assert!("unknown".parse::<LogStream>().is_err());
80    }
81
82    #[test]
83    fn display_matches_as_str() {
84        assert_eq!(LogStream::Stdout.to_string(), "stdout");
85        assert_eq!(LogStream::Stderr.to_string(), "stderr");
86        assert_eq!(LogStream::System.to_string(), "system");
87    }
88
89    #[test]
90    fn as_str_values() {
91        assert_eq!(LogStream::Stdout.as_str(), "stdout");
92        assert_eq!(LogStream::Stderr.as_str(), "stderr");
93        assert_eq!(LogStream::System.as_str(), "system");
94    }
95}