Skip to main content

claude_wrapper/command/
raw.rs

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