1use std::collections::BTreeMap;
9
10use crate::cap::CapId;
11use crate::promise::PromiseId;
12
13#[derive(Debug, Clone, PartialEq)]
15pub enum Value {
16 Null,
18 Bool(bool),
20 Int(i64),
22 Float(f64),
24 Text(String),
26 List(Vec<Value>),
28 Map(BTreeMap<String, Value>),
30 Secret,
32 Module(Vec<u8>),
34 Path(String),
36}
37
38impl Value {
39 pub fn text(value: impl Into<String>) -> Value {
41 Value::Text(value.into())
42 }
43
44 pub fn path(value: impl Into<String>) -> Value {
46 Value::Path(value.into())
47 }
48
49 pub fn list(items: impl IntoIterator<Item = Value>) -> Value {
51 Value::List(items.into_iter().collect())
52 }
53
54 pub fn map<K: Into<String>, I: IntoIterator<Item = (K, Value)>>(entries: I) -> Value {
56 Value::Map(
57 entries
58 .into_iter()
59 .map(|(key, value)| (key.into(), value))
60 .collect(),
61 )
62 }
63
64 pub fn as_text(&self) -> Option<&str> {
66 match self {
67 Value::Text(text) => Some(text),
68 _ => None,
69 }
70 }
71
72 pub fn as_path(&self) -> Option<&str> {
74 match self {
75 Value::Path(path) => Some(path),
76 _ => None,
77 }
78 }
79
80 pub fn is_tainted(&self) -> bool {
82 match self {
83 Value::Secret => true,
84 Value::List(items) => items.iter().any(Value::is_tainted),
85 Value::Map(entries) => entries.values().any(Value::is_tainted),
86 _ => false,
87 }
88 }
89}
90
91#[derive(Debug, Clone, PartialEq)]
93pub enum Arg {
94 Value(Value),
96 Promise(PromiseId),
98 Cap(CapId),
100}
101
102impl Arg {
103 pub fn value(value: Value) -> Arg {
105 Arg::Value(value)
106 }
107
108 pub fn text(value: impl Into<String>) -> Arg {
110 Arg::Value(Value::Text(value.into()))
111 }
112
113 pub fn promise(&self) -> Option<PromiseId> {
115 match self {
116 Arg::Promise(id) => Some(*id),
117 _ => None,
118 }
119 }
120}
121
122#[derive(Debug, Clone, PartialEq)]
124pub struct Call {
125 pub method: String,
127 pub args: Vec<Arg>,
129 pub path_scope: Option<String>,
131 pub redact: bool,
133 pub read_only: bool,
135 pub tool_allows_process: bool,
137 pub budget: crate::budget::Budget,
139}
140
141impl Call {
142 pub fn new(method: impl Into<String>, args: Vec<Arg>) -> Call {
144 Call {
145 method: method.into(),
146 args,
147 path_scope: None,
148 redact: false,
149 read_only: false,
150 tool_allows_process: false,
151 budget: crate::budget::Budget::default(),
152 }
153 }
154
155 pub fn first(&self) -> Option<&Arg> {
157 self.args.first()
158 }
159}
160
161#[derive(Debug, Clone, PartialEq)]
163pub enum Response {
164 Value(Value),
166 Module(Vec<u8>),
168 Labels(Vec<String>),
170}
171
172impl Response {
173 pub fn into_value(self) -> Value {
175 match self {
176 Response::Value(value) => value,
177 Response::Module(bytes) => Value::Module(bytes),
178 Response::Labels(labels) => Value::List(labels.into_iter().map(Value::Text).collect()),
179 }
180 }
181}