openapi_nexus/spec/oas32/spec/
callback.rs1use std::{collections::BTreeMap, error::Error as StdError};
2
3use serde::{Deserialize, Serialize};
4
5use super::PathItem;
6
7#[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize)]
9#[serde(try_from = "CallbackSerde", into = "CallbackSerde")]
10pub struct Callback {
11 pub paths: BTreeMap<String, PathItem>,
13
14 pub extensions: BTreeMap<String, serde_json::Value>,
16}
17
18#[derive(Debug, Deserialize, Serialize)]
19#[serde(transparent)]
20struct CallbackSerde(serde_json::Map<String, serde_json::Value>);
21
22impl TryFrom<CallbackSerde> for Callback {
23 type Error = Box<dyn StdError>;
24
25 fn try_from(CallbackSerde(map): CallbackSerde) -> Result<Self, Self::Error> {
26 let (extensions, paths) = bisect_map(map, |key| key.starts_with("x-"));
27
28 let paths = paths
29 .into_iter()
30 .map(|(key, value)| serde_json::from_value(value).map(|v| (key, v)))
31 .collect::<Result<_, _>>()?;
32
33 Ok(Self {
34 paths,
35 extensions: extensions.into_iter().collect(),
36 })
37 }
38}
39
40fn bisect_map(
41 map: serde_json::Map<String, serde_json::Value>,
42 predicate: fn(&String) -> bool,
43) -> (
44 serde_json::Map<String, serde_json::Value>,
45 serde_json::Map<String, serde_json::Value>,
46) {
47 let mut first = map;
48 let mut second = first.clone();
49
50 first.retain(|key, _| predicate(key));
51 second.retain(|key, _| !predicate(key));
52
53 (first, second)
54}
55
56impl From<Callback> for CallbackSerde {
57 fn from(val: Callback) -> Self {
58 let Callback { paths, extensions } = val;
59
60 CallbackSerde(
61 paths
62 .into_iter()
63 .map(|(key, val)| {
64 (
65 key,
66 serde_json::to_value(val).expect("path item serialization should not fail"),
67 )
68 })
69 .chain(extensions)
70 .collect(),
71 )
72 }
73}