Skip to main content

earl_protocol_bash/
schema.rs

1use std::collections::BTreeMap;
2
3use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7use earl_core::schema::TransportTemplate;
8use earl_core::with::AsJson;
9
10#[derive(Debug, Clone, Deserialize, Serialize, Archive, RkyvSerialize, RkyvDeserialize)]
11#[serde(deny_unknown_fields)]
12pub struct BashOperationTemplate {
13    pub bash: BashScriptTemplate,
14    #[serde(default)]
15    pub stream: bool,
16    pub transport: Option<TransportTemplate>,
17}
18
19#[derive(Debug, Clone, Deserialize, Serialize, Archive, RkyvSerialize, RkyvDeserialize)]
20#[serde(deny_unknown_fields)]
21pub struct BashScriptTemplate {
22    pub script: String,
23    #[rkyv(with = AsJson)]
24    #[serde(default)]
25    pub env: Option<BTreeMap<String, Value>>,
26    pub cwd: Option<String>,
27    pub sandbox: Option<BashSandboxTemplate>,
28}
29
30#[derive(Debug, Clone, Deserialize, Serialize, Archive, RkyvSerialize, RkyvDeserialize)]
31#[serde(deny_unknown_fields)]
32pub struct BashSandboxTemplate {
33    pub network: Option<bool>,
34    pub writable_paths: Option<Vec<String>>,
35    pub max_time_ms: Option<u64>,
36    pub max_output_bytes: Option<u64>,
37    pub max_memory_bytes: Option<u64>,
38    pub max_cpu_time_ms: Option<u64>,
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[test]
46    fn bash_operation_defaults_stream_false() {
47        let json = r#"{"bash":{"script":"echo hello"}}"#;
48        let op: BashOperationTemplate = serde_json::from_str(json).unwrap();
49        assert!(!op.stream);
50    }
51
52    #[test]
53    fn bash_operation_accepts_stream_true() {
54        let json = r#"{"stream":true,"bash":{"script":"echo hello"}}"#;
55        let op: BashOperationTemplate = serde_json::from_str(json).unwrap();
56        assert!(op.stream);
57    }
58}