gemini_adk_rs/
confirmation.rs

1//! Tool confirmation — user confirmation for sensitive tool calls.
2
3use serde::{Deserialize, Serialize};
4
5/// Represents a user's confirmation decision for a tool call.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ToolConfirmation {
8    /// Optional hint text explaining what needs confirmation.
9    pub hint: Option<String>,
10    /// Whether the user confirmed the action.
11    pub confirmed: bool,
12    /// Optional payload with additional context.
13    pub payload: Option<serde_json::Value>,
14}
15
16impl ToolConfirmation {
17    /// Create a confirmed result.
18    pub fn confirmed() -> Self {
19        Self {
20            hint: None,
21            confirmed: true,
22            payload: None,
23        }
24    }
25
26    /// Create a denied result with a hint explaining why.
27    pub fn denied(hint: impl Into<String>) -> Self {
28        Self {
29            hint: Some(hint.into()),
30            confirmed: false,
31            payload: None,
32        }
33    }
34
35    /// Attach a payload to this confirmation.
36    pub fn with_payload(mut self, payload: serde_json::Value) -> Self {
37        self.payload = Some(payload);
38        self
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn confirmed_constructor() {
48        let c = ToolConfirmation::confirmed();
49        assert!(c.confirmed);
50        assert!(c.hint.is_none());
51        assert!(c.payload.is_none());
52    }
53
54    #[test]
55    fn denied_constructor() {
56        let c = ToolConfirmation::denied("Too dangerous");
57        assert!(!c.confirmed);
58        assert_eq!(c.hint.as_deref(), Some("Too dangerous"));
59    }
60
61    #[test]
62    fn with_payload() {
63        let c =
64            ToolConfirmation::confirmed().with_payload(serde_json::json!({"reason": "approved"}));
65        assert!(c.confirmed);
66        assert_eq!(c.payload.unwrap()["reason"], "approved");
67    }
68
69    #[test]
70    fn serde_roundtrip() {
71        let c =
72            ToolConfirmation::denied("risky").with_payload(serde_json::json!({"level": "high"}));
73        let json = serde_json::to_string(&c).unwrap();
74        let parsed: ToolConfirmation = serde_json::from_str(&json).unwrap();
75        assert!(!parsed.confirmed);
76        assert_eq!(parsed.hint.as_deref(), Some("risky"));
77        assert_eq!(parsed.payload.unwrap()["level"], "high");
78    }
79}