Skip to main content

adk_sandbox/
types.rs

1//! Core types for sandbox execution: [`Language`], [`ExecRequest`], and [`ExecResult`].
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::fmt;
6use std::time::Duration;
7
8/// Supported execution languages.
9///
10/// Each variant maps to a specific interpreter or compiler used by the backend.
11///
12/// # Example
13///
14/// ```rust
15/// use adk_sandbox::Language;
16///
17/// let lang = Language::Rust;
18/// assert_eq!(lang.to_string(), "rust");
19/// ```
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
21#[serde(rename_all = "lowercase")]
22pub enum Language {
23    /// Rust source compiled with `rustc`.
24    Rust,
25    /// Python source executed with `python3`.
26    Python,
27    /// JavaScript source executed with `node`.
28    JavaScript,
29    /// TypeScript source (requires a compatible runtime).
30    TypeScript,
31    /// Pre-compiled WebAssembly module bytes.
32    Wasm,
33    /// Raw shell command executed via `sh -c`.
34    Command,
35}
36
37impl fmt::Display for Language {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        match self {
40            Language::Rust => write!(f, "rust"),
41            Language::Python => write!(f, "python"),
42            Language::JavaScript => write!(f, "javascript"),
43            Language::TypeScript => write!(f, "typescript"),
44            Language::Wasm => write!(f, "wasm"),
45            Language::Command => write!(f, "command"),
46        }
47    }
48}
49
50/// A request to execute code in a sandbox.
51///
52/// `ExecRequest` intentionally has no `Default` implementation — callers must
53/// explicitly set the `timeout` to avoid unbounded execution.
54///
55/// # Example
56///
57/// ```rust
58/// use adk_sandbox::{ExecRequest, Language};
59/// use std::time::Duration;
60/// use std::collections::HashMap;
61///
62/// let request = ExecRequest {
63///     language: Language::Python,
64///     code: "print('hello')".to_string(),
65///     stdin: None,
66///     timeout: Duration::from_secs(30),
67///     memory_limit_mb: None,
68///     env: HashMap::new(),
69/// };
70/// ```
71#[derive(Debug, Clone)]
72pub struct ExecRequest {
73    /// The language of the code to execute.
74    pub language: Language,
75    /// The source code or command to execute.
76    pub code: String,
77    /// Optional standard input to feed to the process.
78    pub stdin: Option<String>,
79    /// Maximum wall-clock time allowed for execution. No default — must be set explicitly.
80    pub timeout: Duration,
81    /// Optional memory limit in megabytes. Only enforced by `WasmBackend`.
82    pub memory_limit_mb: Option<u32>,
83    /// Environment variables passed to the child process. The backend clears
84    /// the inherited environment and sets only these variables.
85    pub env: HashMap<String, String>,
86}
87
88/// The result of a sandbox execution.
89///
90/// Non-zero `exit_code` is a valid result, not an error. The caller decides
91/// how to interpret the exit code.
92///
93/// # Example
94///
95/// ```rust
96/// use adk_sandbox::ExecResult;
97/// use std::time::Duration;
98///
99/// let result = ExecResult {
100///     stdout: "hello\n".to_string(),
101///     stderr: String::new(),
102///     exit_code: 0,
103///     duration: Duration::from_millis(42),
104/// };
105/// assert_eq!(result.exit_code, 0);
106/// ```
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct ExecResult {
109    /// Captured standard output (UTF-8, truncated to 1 MB by backends).
110    pub stdout: String,
111    /// Captured standard error (UTF-8, truncated to 1 MB by backends).
112    pub stderr: String,
113    /// Process exit code. 0 typically means success.
114    pub exit_code: i32,
115    /// Wall-clock duration of the execution.
116    pub duration: Duration,
117}