1use serde::de::{self, Deserializer, MapAccess, SeqAccess, Visitor};
2use serde::{Deserialize, Serialize, Serializer};
3use std::collections::HashMap;
4use std::convert::Infallible;
5use std::fmt;
6use std::marker::PhantomData;
7use std::str::FromStr;
8
9#[allow(clippy::trivially_copy_pass_by_ref)]
12pub(crate) fn is_false(value: &bool) -> bool {
13 !value
14}
15
16pub fn serialize_map_sorted<S, V>(
19 map: &HashMap<String, V>,
20 serializer: S,
21) -> Result<S::Ok, S::Error>
22where
23 S: Serializer,
24 V: Serialize,
25{
26 let mut entries: Vec<_> = map.iter().collect();
27 entries.sort_by_key(|(key, _)| *key);
28 serializer.collect_map(entries)
29}
30
31pub fn serialize_optional_map_sorted<S, V>(
37 map: &Option<HashMap<String, V>>,
38 serializer: S,
39) -> Result<S::Ok, S::Error>
40where
41 S: Serializer,
42 V: Serialize,
43{
44 match map {
45 Some(map) => serialize_map_sorted(map, serializer),
46 None => serializer.serialize_none(),
47 }
48}
49
50pub fn to_canonical_string(value: &serde_json::Value) -> String {
53 fn sorted(value: &serde_json::Value) -> serde_json::Value {
54 match value {
55 serde_json::Value::Object(map) => {
56 let mut entries: Vec<_> = map.iter().collect();
57 entries.sort_by_key(|(key, _)| *key);
58 let mut out = serde_json::Map::new();
59 for (key, value) in entries {
60 out.insert(key.clone(), sorted(value));
61 }
62 serde_json::Value::Object(out)
63 }
64 serde_json::Value::Array(items) => {
65 serde_json::Value::Array(items.iter().map(sorted).collect())
66 }
67 serde_json::Value::Null
68 | serde_json::Value::Bool(_)
69 | serde_json::Value::Number(_)
70 | serde_json::Value::String(_) => value.clone(),
71 }
72 }
73 sorted(value).to_string()
74}
75
76pub fn merge(a: serde_json::Value, b: serde_json::Value) -> serde_json::Value {
77 match (a, b) {
78 (serde_json::Value::Object(mut a_map), serde_json::Value::Object(b_map)) => {
79 b_map.into_iter().for_each(|(key, value)| {
80 a_map.insert(key, value);
81 });
82 serde_json::Value::Object(a_map)
83 }
84 (a, _) => a,
85 }
86}
87
88pub(crate) fn merge_params(
92 existing: Option<serde_json::Value>,
93 params: Option<serde_json::Value>,
94) -> Option<serde_json::Value> {
95 Some(match (existing, params?) {
96 (Some(existing), params) => merge(existing, params),
97 (None, params) => params,
98 })
99}
100
101#[cfg_attr(not(any(feature = "image", feature = "audio")), allow(dead_code))]
103pub fn merge_inplace(a: &mut serde_json::Value, b: serde_json::Value) {
104 if let (serde_json::Value::Object(a_map), serde_json::Value::Object(b_map)) = (a, b) {
105 b_map.into_iter().for_each(|(key, value)| {
106 a_map.insert(key, value);
107 });
108 }
109}
110
111pub fn value_to_json_string(value: &serde_json::Value) -> String {
116 match value {
117 serde_json::Value::String(s) => s.clone(),
118 other => other.to_string(),
119 }
120}
121
122pub fn serialize_json_value(value: &serde_json::Value) -> String {
124 value.to_string()
125}
126
127pub fn deserialize_json_string_or_value<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
131where
132 D: Deserializer<'de>,
133{
134 let value = Option::<serde_json::Value>::deserialize(deserializer)?;
135 Ok(match value {
136 None | Some(serde_json::Value::Null) => None,
137 Some(v) => Some(value_to_json_string(&v)),
138 })
139}
140
141pub fn parse_tool_arguments(arguments: &str) -> serde_json::Result<serde_json::Value> {
144 if arguments.trim().is_empty() {
145 return Ok(serde_json::Value::Object(serde_json::Map::new()));
146 }
147
148 serde_json::from_str(arguments)
149}
150
151pub fn parse_partial_object(text: &str) -> Option<serde_json::Map<String, serde_json::Value>> {
155 const MAX_ATTEMPTS: usize = 256;
158 let mut stack = Vec::new();
159 let mut in_string = false;
160 let mut escaped = false;
161 let mut cuts: Vec<(usize, Vec<u8>, bool)> = Vec::new();
163 let bytes = text.as_bytes();
164 for (at, byte) in bytes.iter().enumerate() {
165 if in_string {
166 match (escaped, *byte) {
167 (true, _) => escaped = false,
168 (false, b'\\') => escaped = true,
169 (false, b'"') => {
170 in_string = false;
171 cuts.push((at + 1, stack.clone(), false));
172 }
173 (false, _) => {}
174 }
175 continue;
176 }
177 match byte {
178 b'"' => in_string = true,
179 b'{' | b'[' => {
180 stack.push(*byte);
181 cuts.push((at + 1, stack.clone(), false));
182 }
183 b'}' | b']' => {
184 stack.pop();
185 cuts.push((at + 1, stack.clone(), false));
186 }
187 b if b.is_ascii_alphanumeric() || *b == b'.' || *b == b'-' || *b == b'+' => {
188 let next = bytes.get(at + 1).copied();
189 if !next.is_some_and(|n| {
190 n.is_ascii_alphanumeric() || n == b'.' || n == b'-' || n == b'+'
191 }) {
192 cuts.push((at + 1, stack.clone(), false));
193 }
194 }
195 _ => {}
196 }
197 }
198 if in_string {
199 let at = text.len() - usize::from(escaped);
200 cuts.push((at, stack.clone(), true));
201 }
202 cuts.iter()
203 .rev()
204 .take(MAX_ATTEMPTS)
205 .find_map(|(at, open, quote)| {
206 let mut candidate = text.get(..*at)?.to_owned();
207 if *quote {
208 candidate.push('"');
209 }
210 for container in open.iter().rev() {
211 candidate.push(if *container == b'{' { '}' } else { ']' });
212 }
213 match serde_json::from_str(&candidate) {
214 Ok(serde_json::Value::Object(object)) => Some(object),
215 _ => None,
216 }
217 })
218}
219
220pub fn parse_partial_arguments(text: &str) -> serde_json::Map<String, serde_json::Value> {
238 if text.trim().is_empty() {
239 return serde_json::Map::new();
240 }
241 let repaired = repair_json(text);
242 let complete = serde_json::from_str(text)
243 .ok()
244 .or_else(|| serde_json::from_str(&repaired).ok());
245 if let Some(value) = complete {
246 return match value {
247 serde_json::Value::Object(object) => object,
248 _ => serde_json::Map::new(),
249 };
250 }
251 let cut = without_partial_escape(&repaired);
252 parse_partial_object(cut)
253 .or_else(|| parse_partial_object(text))
254 .unwrap_or_default()
255}
256
257fn repair_json(text: &str) -> String {
261 let mut repaired = String::with_capacity(text.len());
262 let mut in_string = false;
263 let mut chars = text.chars().peekable();
264 while let Some(c) = chars.next() {
265 if !in_string {
266 in_string = c == '"';
267 repaired.push(c);
268 continue;
269 }
270 match c {
271 '"' => {
272 in_string = false;
273 repaired.push(c);
274 }
275 '\\' => match chars.peek() {
276 Some('"' | '\\' | '/' | 'b' | 'f' | 'n' | 'r' | 't' | 'u') => {
277 repaired.push(c);
278 if let Some(next) = chars.next() {
279 repaired.push(next);
280 }
281 }
282 None => repaired.push(c),
284 Some(_) => repaired.push_str("\\\\"),
285 },
286 '\n' => repaired.push_str("\\n"),
287 '\r' => repaired.push_str("\\r"),
288 '\t' => repaired.push_str("\\t"),
289 c if c.is_control() => {
290 use std::fmt::Write as _;
291 let _ = write!(repaired, "\\u{:04x}", u32::from(c));
293 }
294 c => repaired.push(c),
295 }
296 }
297 repaired
298}
299
300fn without_partial_escape(text: &str) -> &str {
303 let bytes = text.as_bytes();
304 let tail = bytes.len().saturating_sub(5);
305 let Some(at) = (tail..bytes.len())
306 .rev()
307 .find(|at| bytes.get(*at..*at + 2) == Some(b"\\u"))
308 else {
309 return text;
310 };
311 let digits = bytes.get(at + 2..).unwrap_or_default();
312 let escaping = bytes
314 .get(..at)
315 .unwrap_or_default()
316 .iter()
317 .rev()
318 .take_while(|byte| **byte == b'\\')
319 .count();
320 if digits.len() < 4 && digits.iter().all(u8::is_ascii_hexdigit) && escaping % 2 == 0 {
321 text.get(..at).unwrap_or(text)
322 } else {
323 text
324 }
325}
326
327pub mod stringified_json {
330 use super::parse_tool_arguments;
331 use serde::{self, Deserialize, Deserializer, Serializer};
332
333 pub fn serialize<S>(value: &serde_json::Value, serializer: S) -> Result<S::Ok, S::Error>
334 where
335 S: Serializer,
336 {
337 let s = value.to_string();
338 serializer.serialize_str(&s)
339 }
340
341 pub fn deserialize<'de, D>(deserializer: D) -> Result<serde_json::Value, D::Error>
342 where
343 D: Deserializer<'de>,
344 {
345 let s = String::deserialize(deserializer)?;
346 if s.trim().is_empty() {
347 return Ok(serde_json::Value::Object(serde_json::Map::new()));
348 }
349 serde_json::from_str(&s).map_err(serde::de::Error::custom)
350 }
351
352 pub fn deserialize_maybe_stringified<'de, D>(
355 deserializer: D,
356 ) -> Result<serde_json::Value, D::Error>
357 where
358 D: Deserializer<'de>,
359 {
360 match serde_json::Value::deserialize(deserializer)? {
361 serde_json::Value::String(s) => {
362 parse_tool_arguments(&s).map_err(serde::de::Error::custom)
363 }
364 other => Ok(other),
365 }
366 }
367}
368
369pub fn string_or_vec<'de, T, D>(deserializer: D) -> Result<Vec<T>, D::Error>
372where
373 T: Deserialize<'de> + FromStr<Err = Infallible>,
374 D: Deserializer<'de>,
375{
376 struct StringOrVec<T>(PhantomData<fn() -> T>);
377
378 impl<'de, T> Visitor<'de> for StringOrVec<T>
379 where
380 T: Deserialize<'de> + FromStr<Err = Infallible>,
381 {
382 type Value = Vec<T>;
383
384 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
385 formatter.write_str("a string, sequence, or null")
386 }
387
388 fn visit_str<E>(self, value: &str) -> Result<Vec<T>, E>
389 where
390 E: de::Error,
391 {
392 let item = FromStr::from_str(value).map_err(de::Error::custom)?;
393 Ok(vec![item])
394 }
395
396 fn visit_seq<A>(self, seq: A) -> Result<Vec<T>, A::Error>
397 where
398 A: SeqAccess<'de>,
399 {
400 Deserialize::deserialize(de::value::SeqAccessDeserializer::new(seq))
401 }
402
403 fn visit_map<M>(self, map: M) -> Result<Vec<T>, M::Error>
404 where
405 M: MapAccess<'de>,
406 {
407 let item = Deserialize::deserialize(de::value::MapAccessDeserializer::new(map))?;
408 Ok(vec![item])
409 }
410
411 fn visit_none<E>(self) -> Result<Vec<T>, E>
412 where
413 E: de::Error,
414 {
415 Ok(vec![])
416 }
417
418 fn visit_unit<E>(self) -> Result<Vec<T>, E>
419 where
420 E: de::Error,
421 {
422 Ok(vec![])
423 }
424 }
425
426 deserializer.deserialize_any(StringOrVec(PhantomData))
427}
428
429pub fn null_or_default<'de, T, D>(deserializer: D) -> Result<T, D::Error>
434where
435 T: Deserialize<'de> + Default,
436 D: Deserializer<'de>,
437{
438 Ok(Option::<T>::deserialize(deserializer)?.unwrap_or_default())
439}
440
441#[cfg(test)]
442mod tests;
443
444pub trait Lenient {
459 fn str(&self, key: &str) -> Option<&str>;
461 fn u64(&self, key: &str) -> Option<u64>;
463 fn i64(&self, key: &str) -> Option<i64>;
465 fn f64(&self, key: &str) -> Option<f64>;
467 fn bool(&self, key: &str) -> Option<bool>;
469 fn obj(&self, key: &str) -> Option<&serde_json::Map<String, serde_json::Value>>;
471 fn arr(&self, key: &str) -> &[serde_json::Value];
473 fn at(&self, pointer: &str) -> Option<&serde_json::Value>;
475 fn as_u64_lenient(&self) -> Option<u64>;
477}
478
479impl Lenient for serde_json::Value {
480 fn str(&self, key: &str) -> Option<&str> {
481 self.get(key)?.as_str()
482 }
483
484 fn u64(&self, key: &str) -> Option<u64> {
485 self.get(key)?.as_u64_lenient()
486 }
487
488 fn i64(&self, key: &str) -> Option<i64> {
489 match self.get(key)? {
490 serde_json::Value::Number(number) => number.as_i64(),
491 serde_json::Value::String(text) => text.trim().parse().ok(),
492 _ => None,
493 }
494 }
495
496 fn f64(&self, key: &str) -> Option<f64> {
497 match self.get(key)? {
498 serde_json::Value::Number(number) => number.as_f64(),
499 serde_json::Value::String(text) => text.trim().parse().ok(),
500 _ => None,
501 }
502 }
503
504 fn bool(&self, key: &str) -> Option<bool> {
505 self.get(key)?.as_bool()
506 }
507
508 fn obj(&self, key: &str) -> Option<&serde_json::Map<String, serde_json::Value>> {
509 self.get(key)?.as_object()
510 }
511
512 fn arr(&self, key: &str) -> &[serde_json::Value] {
513 self.get(key)
514 .and_then(serde_json::Value::as_array)
515 .map_or(&[], Vec::as_slice)
516 }
517
518 fn at(&self, pointer: &str) -> Option<&serde_json::Value> {
519 self.pointer(pointer).filter(|value| !value.is_null())
520 }
521
522 fn as_u64_lenient(&self) -> Option<u64> {
523 match self {
524 serde_json::Value::Number(number) => number.as_u64().or_else(|| {
525 number
526 .as_f64()
527 .filter(|float| *float >= 0.0 && float.fract() == 0.0)
528 .map(|float| float as u64)
529 }),
530 serde_json::Value::String(text) => text.trim().parse().ok(),
531 _ => None,
532 }
533 }
534}