Skip to main content

squib_api/schemas/
serial.rs

1//! `/serial` PUT body — guest-side serial console destination.
2
3use serde::{Deserialize, Serialize};
4
5use super::common::SafePath;
6
7/// Raw `/serial` PUT body off the wire.
8#[derive(Debug, Clone, Deserialize)]
9#[serde(deny_unknown_fields)]
10pub struct RawSerialConfig {
11    /// Path of the file or named pipe receiving serial output.
12    pub log_path: String,
13}
14
15/// Validated `/serial` PUT body.
16#[derive(Debug, Clone, Serialize)]
17#[non_exhaustive]
18pub struct SerialConfig {
19    /// Validated host path.
20    pub log_path: SafePath,
21}
22
23impl TryFrom<RawSerialConfig> for SerialConfig {
24    type Error = String;
25
26    fn try_from(raw: RawSerialConfig) -> Result<Self, Self::Error> {
27        Ok(Self {
28            log_path: SafePath::new(raw.log_path).map_err(|e| format!("Invalid log_path: {e}"))?,
29        })
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn test_should_accept_minimal_serial_config() {
39        let cfg = SerialConfig::try_from(RawSerialConfig {
40            log_path: "/tmp/serial.out".into(),
41        })
42        .unwrap();
43        assert_eq!(cfg.log_path.as_path().as_os_str(), "/tmp/serial.out");
44    }
45
46    #[test]
47    fn test_should_reject_empty_log_path() {
48        assert!(
49            SerialConfig::try_from(RawSerialConfig {
50                log_path: String::new(),
51            })
52            .is_err()
53        );
54    }
55}