Skip to main content

claude_wrapper/command/
raw.rs

1use crate::Claude;
2use crate::command::ClaudeCommand;
3use crate::error::Result;
4use crate::exec::{self, CommandOutput};
5
6/// Escape hatch for running arbitrary claude subcommands not yet
7/// covered by dedicated command builders.
8///
9/// # Example
10///
11/// ```no_run
12/// use claude_wrapper::{Claude, ClaudeCommand, RawCommand};
13///
14/// # async fn example() -> claude_wrapper::Result<()> {
15/// let claude = Claude::builder().build()?;
16///
17/// let output = RawCommand::new("agents")
18///     .arg("--setting-sources")
19///     .arg("user,project")
20///     .execute(&claude)
21///     .await?;
22///
23/// println!("{}", output.stdout);
24/// # Ok(())
25/// # }
26/// ```
27#[derive(Debug, Clone)]
28pub struct RawCommand {
29    command_args: Vec<String>,
30}
31
32impl RawCommand {
33    /// Create a new raw command with the given subcommand.
34    #[must_use]
35    pub fn new(subcommand: impl Into<String>) -> Self {
36        Self {
37            command_args: vec![subcommand.into()],
38        }
39    }
40
41    /// Add a single argument.
42    #[must_use]
43    pub fn arg(mut self, arg: impl Into<String>) -> Self {
44        self.command_args.push(arg.into());
45        self
46    }
47
48    /// Add multiple arguments.
49    #[must_use]
50    pub fn args(mut self, args: impl IntoIterator<Item = impl Into<String>>) -> Self {
51        self.command_args.extend(args.into_iter().map(Into::into));
52        self
53    }
54}
55
56impl ClaudeCommand for RawCommand {
57    type Output = CommandOutput;
58
59    fn args(&self) -> Vec<String> {
60        self.command_args.clone()
61    }
62
63    async fn execute(&self, claude: &Claude) -> Result<CommandOutput> {
64        exec::run_claude(claude, self.args()).await
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    use crate::command::ClaudeCommand;
72
73    #[test]
74    fn test_raw_command_args() {
75        let cmd = RawCommand::new("agents")
76            .arg("--setting-sources")
77            .arg("user,project");
78
79        assert_eq!(
80            ClaudeCommand::args(&cmd),
81            vec!["agents", "--setting-sources", "user,project"]
82        );
83    }
84
85    #[test]
86    fn test_raw_command_with_args() {
87        let cmd = RawCommand::new("plugin").args(["list", "--scope", "user"]);
88
89        assert_eq!(
90            ClaudeCommand::args(&cmd),
91            vec!["plugin", "list", "--scope", "user"]
92        );
93    }
94}