theway_daemon/executor/
mod.rs1use std::sync::Arc;
20
21use theway_core::executor::{ExecutorKind, ToolExecutor};
22
23pub mod file_lock;
24pub mod local;
25pub mod sandbox;
26
27pub fn parse_executor_kind(raw: &str) -> Result<ExecutorKind, String> {
30 match raw.trim().to_ascii_lowercase().as_str() {
31 "local" => Ok(ExecutorKind::Local),
32 "sandbox" => Ok(ExecutorKind::Sandbox),
33 other => Err(format!(
34 "invalid executor kind {other:?}: expected \"local\" or \"sandbox\""
35 )),
36 }
37}
38
39pub fn executor_for_kind(
43 kind: ExecutorKind,
44 cwd: impl Into<std::path::PathBuf>,
45) -> Arc<dyn ToolExecutor> {
46 match kind {
47 ExecutorKind::Local => Arc::new(local::LocalExecutor::with_cwd(cwd)),
48 ExecutorKind::Sandbox => Arc::new(sandbox::SandboxExecutor::new()),
49 }
50}
51
52pub fn default_executor() -> Arc<dyn ToolExecutor> {
55 executor_for_cwd(std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(".")))
56}
57
58pub fn executor_for_cwd(cwd: impl Into<std::path::PathBuf>) -> Arc<dyn ToolExecutor> {
61 executor_for_kind(ExecutorKind::Local, cwd)
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn parse_executor_kind_accepts_both_values_case_insensitively() {
70 assert_eq!(parse_executor_kind("local").unwrap(), ExecutorKind::Local);
71 assert_eq!(
72 parse_executor_kind("Sandbox").unwrap(),
73 ExecutorKind::Sandbox
74 );
75 assert_eq!(
76 parse_executor_kind(" SANDBOX ").unwrap(),
77 ExecutorKind::Sandbox
78 );
79 assert!(parse_executor_kind("docker").is_err());
80 assert!(parse_executor_kind("").is_err());
81 }
82
83 #[tokio::test]
84 async fn executor_for_cwd_roots_local_executor_at_cwd() {
85 let dir = tempfile::tempdir().unwrap();
86 std::fs::write(dir.path().join("probe.txt"), "ok").unwrap();
87 let executor = executor_for_cwd(dir.path());
88 assert_eq!(executor.kind().await, ExecutorKind::Local);
89 assert_eq!(
90 executor
91 .read_file(std::path::Path::new("probe.txt"))
92 .await
93 .unwrap(),
94 "ok"
95 );
96 }
97
98 #[tokio::test]
99 async fn executor_for_kind_returns_the_configured_environment() {
100 let dir = tempfile::tempdir().unwrap();
101 let local = executor_for_kind(ExecutorKind::Local, dir.path());
102 assert_eq!(local.kind().await, ExecutorKind::Local);
103 let sandbox = executor_for_kind(ExecutorKind::Sandbox, dir.path());
104 assert_eq!(sandbox.kind().await, ExecutorKind::Sandbox);
105 }
106}