Skip to main content

claude_code_rs/types/
permissions.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::future::Future;
4use std::pin::Pin;
5use std::sync::Arc;
6
7/// Permission mode for tool usage.
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
9#[serde(rename_all = "lowercase")]
10pub enum PermissionMode {
11    /// Default permissions - prompt user for dangerous tools.
12    Default,
13    /// Accept all tool uses without prompting.
14    AcceptAll,
15    /// Deny all tool uses.
16    DenyAll,
17    /// Use allowed-tools list from CLI config.
18    AllowedTools,
19}
20
21impl Default for PermissionMode {
22    fn default() -> Self {
23        Self::Default
24    }
25}
26
27/// Result from a permission check callback.
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct PermissionResult {
30    /// Whether the tool use is allowed.
31    pub allowed: bool,
32    /// Optional reason for denial.
33    #[serde(default, skip_serializing_if = "Option::is_none")]
34    pub reason: Option<String>,
35}
36
37impl PermissionResult {
38    pub fn allow() -> Self {
39        Self {
40            allowed: true,
41            reason: None,
42        }
43    }
44
45    pub fn deny(reason: impl Into<String>) -> Self {
46        Self {
47            allowed: false,
48            reason: Some(reason.into()),
49        }
50    }
51}
52
53/// Input provided to the can_use_tool callback.
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct CanUseToolInput {
56    pub tool_name: String,
57    pub input: Value,
58}
59
60/// Async callback for permission checks.
61pub type CanUseToolCallback = Arc<
62    dyn Fn(CanUseToolInput) -> Pin<Box<dyn Future<Output = PermissionResult> + Send>>
63        + Send
64        + Sync,
65>;
66
67/// Helper to create a CanUseToolCallback from a closure.
68pub fn permission_callback<F, Fut>(f: F) -> CanUseToolCallback
69where
70    F: Fn(CanUseToolInput) -> Fut + Send + Sync + 'static,
71    Fut: Future<Output = PermissionResult> + Send + 'static,
72{
73    Arc::new(move |input| Box::pin(f(input)))
74}