1use std::collections::BTreeMap;
15use std::fmt;
16use std::str::FromStr;
17
18use serde_json::value::RawValue;
19
20pub type Object = BTreeMap<String, Value>;
22
23#[derive(Debug, Clone, PartialEq, Eq)]
30pub struct Number(String);
31
32impl Number {
33 #[must_use]
35 pub fn as_str(&self) -> &str {
36 &self.0
37 }
38
39 #[must_use]
41 pub fn as_i64(&self) -> Option<i64> {
42 self.as_str().parse().ok()
43 }
44
45 #[must_use]
47 pub fn as_u64(&self) -> Option<u64> {
48 self.as_str().parse().ok()
49 }
50}
51
52impl fmt::Display for Number {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 f.write_str(self.as_str())
55 }
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub struct NotANumber;
61
62impl fmt::Display for NotANumber {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 f.write_str("not a JSON number")
65 }
66}
67
68impl std::error::Error for NotANumber {}
69
70impl FromStr for Number {
71 type Err = NotANumber;
72
73 fn from_str(text: &str) -> Result<Self, Self::Err> {
74 let numeric = matches!(text.as_bytes().first(), Some(b'-' | b'0'..=b'9'))
75 && matches!(text.as_bytes().last(), Some(b'0'..=b'9'));
76 if !numeric {
77 return Err(NotANumber);
78 }
79 serde_json::from_str::<&RawValue>(text).map_err(|_| NotANumber)?;
80 Ok(Self(String::from(text)))
81 }
82}
83
84impl From<i64> for Number {
85 fn from(value: i64) -> Self {
86 Self(value.to_string())
87 }
88}
89
90impl From<i32> for Number {
91 fn from(value: i32) -> Self {
92 Self::from(i64::from(value))
93 }
94}
95
96impl From<u32> for Number {
97 fn from(value: u32) -> Self {
98 Self::from(i64::from(value))
99 }
100}
101
102impl serde::Serialize for Number {
103 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
104 match self.as_i64() {
108 Some(whole) if self.as_str() != "-0" => serializer.serialize_i64(whole),
109 _ => {
110 let raw = serde_json::from_str::<&RawValue>(self.as_str())
111 .map_err(serde::ser::Error::custom)?;
112 serde::Serialize::serialize(raw, serializer)
113 }
114 }
115 }
116}
117
118#[derive(Debug, Clone, Default, PartialEq, Eq)]
124pub enum Value {
125 #[default]
127 Null,
128 Bool(bool),
130 Number(Number),
132 String(String),
134 Array(Vec<Value>),
136 Object(Object),
138}
139
140impl Value {
141 #[must_use]
143 pub fn get(&self, key: &str) -> Option<&Self> {
144 match self {
145 Self::Object(object) => object.get(key),
146 _ => None,
147 }
148 }
149
150 #[must_use]
152 pub const fn as_object(&self) -> Option<&Object> {
153 match self {
154 Self::Object(object) => Some(object),
155 _ => None,
156 }
157 }
158
159 #[must_use]
161 pub fn as_array(&self) -> Option<&[Self]> {
162 match self {
163 Self::Array(items) => Some(items),
164 _ => None,
165 }
166 }
167
168 #[must_use]
170 pub fn as_str(&self) -> Option<&str> {
171 match self {
172 Self::String(text) => Some(text),
173 _ => None,
174 }
175 }
176
177 #[must_use]
179 pub const fn is_null(&self) -> bool {
180 matches!(self, Self::Null)
181 }
182
183 pub fn into_serde_json(
201 self,
202 path: &mut Path,
203 ) -> Result<serde_json::Value, ValueConversionError> {
204 match self {
205 Self::Null => Ok(serde_json::Value::Null),
206 Self::Bool(flag) => Ok(serde_json::Value::Bool(flag)),
207 Self::Number(number) => convert_number(&number, path).map(serde_json::Value::Number),
208 Self::String(text) => Ok(serde_json::Value::String(text)),
209 Self::Array(items) => {
210 let mut converted = Vec::with_capacity(items.len());
211 for (index, item) in items.into_iter().enumerate() {
212 converted.push(path.with_index("", index, |path| item.into_serde_json(path))?);
213 }
214 Ok(serde_json::Value::Array(converted))
215 }
216 Self::Object(members) => {
217 let mut converted = serde_json::Map::with_capacity(members.len());
218 for (key, member) in members {
219 let value = convert_member(&key, member, path)?;
220 converted.insert(key, value);
221 }
222 Ok(serde_json::Value::Object(converted))
223 }
224 }
225 }
226
227 pub fn to_serde_json(
238 &self,
239 path: &mut Path,
240 ) -> Result<serde_json::Value, ValueConversionError> {
241 self.clone().into_serde_json(path)
242 }
243
244 #[must_use]
253 pub fn from_serde_json(value: serde_json::Value) -> Self {
254 match value {
255 serde_json::Value::Null => Self::Null,
256 serde_json::Value::Bool(flag) => Self::Bool(flag),
257 serde_json::Value::Number(number) => Self::Number(Number(number.to_string())),
258 serde_json::Value::String(text) => Self::String(text),
259 serde_json::Value::Array(items) => {
260 Self::Array(items.into_iter().map(Self::from_serde_json).collect())
261 }
262 serde_json::Value::Object(members) => Self::Object(
263 members
264 .into_iter()
265 .map(|(key, member)| (key, Self::from_serde_json(member)))
266 .collect(),
267 ),
268 }
269 }
270}
271
272#[derive(Debug, Clone, PartialEq, Eq)]
274pub enum ValueConversionError {
275 LossyNumber {
277 path: String,
279 lexical: String,
281 rendered: String,
283 },
284 UnrepresentableNumber {
286 path: String,
288 lexical: String,
290 },
291}
292
293impl fmt::Display for ValueConversionError {
294 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
295 match self {
296 Self::LossyNumber {
297 path,
298 lexical,
299 rendered,
300 } => write!(f, "{path}: serde_json writes {lexical} as {rendered}"),
301 Self::UnrepresentableNumber { path, lexical } => {
302 write!(f, "{path}: serde_json holds no number {lexical}")
303 }
304 }
305 }
306}
307
308impl std::error::Error for ValueConversionError {}
309
310fn convert_number(
311 number: &Number,
312 path: &Path,
313) -> Result<serde_json::Number, ValueConversionError> {
314 let lexical = number.as_str();
315 let converted = serde_json::Number::from_str(lexical).map_err(|_| {
316 ValueConversionError::UnrepresentableNumber {
317 path: path.location(),
318 lexical: String::from(lexical),
319 }
320 })?;
321 let rendered = converted.to_string();
322 if rendered == lexical {
323 return Ok(converted);
324 }
325 Err(ValueConversionError::LossyNumber {
326 path: path.location(),
327 lexical: String::from(lexical),
328 rendered,
329 })
330}
331
332fn convert_member(
333 key: &str,
334 member: Value,
335 path: &mut Path,
336) -> Result<serde_json::Value, ValueConversionError> {
337 match member {
338 Value::Array(items) => {
339 let mut converted = Vec::with_capacity(items.len());
340 for (index, item) in items.into_iter().enumerate() {
341 converted.push(path.with_index(key, index, |path| item.into_serde_json(path))?);
342 }
343 Ok(serde_json::Value::Array(converted))
344 }
345 other => path.with(key, |path| other.into_serde_json(path)),
346 }
347}
348
349impl From<i32> for Value {
350 fn from(value: i32) -> Self {
351 Self::Number(Number::from(value))
352 }
353}
354
355impl From<u32> for Value {
356 fn from(value: u32) -> Self {
357 Self::Number(Number::from(value))
358 }
359}
360
361impl serde::Serialize for Value {
362 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
363 match self {
364 Self::Null => serializer.serialize_unit(),
365 Self::Bool(flag) => serializer.serialize_bool(*flag),
366 Self::Number(number) => serde::Serialize::serialize(number, serializer),
367 Self::String(text) => serializer.serialize_str(text),
368 Self::Array(items) => serde::Serialize::serialize(items, serializer),
369 Self::Object(object) => serde::Serialize::serialize(object, serializer),
370 }
371 }
372}
373
374impl<'de> serde::Deserialize<'de> for Value {
375 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
376 let raw = <Box<RawValue> as serde::Deserialize>::deserialize(deserializer)?;
377 read_raw(raw.get(), 0).map_err(serde::de::Error::custom)
378 }
379}
380
381const NESTING_LIMIT: usize = 128;
384
385fn read_raw(raw: &str, depth: usize) -> Result<Value, serde_json::Error> {
389 let text = raw.trim();
390 if depth > NESTING_LIMIT {
391 return Err(serde::de::Error::custom("recursion limit exceeded"));
392 }
393 match text.as_bytes().first() {
394 Some(b'{') => {
395 let members: BTreeMap<String, Box<RawValue>> = serde_json::from_str(text)?;
396 let mut object = Object::new();
397 for (key, member) in members {
398 object.insert(key, read_raw(member.get(), depth + 1)?);
399 }
400 Ok(Value::Object(object))
401 }
402 Some(b'[') => {
403 let members: Vec<Box<RawValue>> = serde_json::from_str(text)?;
404 let mut items = Vec::with_capacity(members.len());
405 for member in members {
406 items.push(read_raw(member.get(), depth + 1)?);
407 }
408 Ok(Value::Array(items))
409 }
410 Some(b'"') => Ok(Value::String(serde_json::from_str(text)?)),
411 Some(b't' | b'f') => Ok(Value::Bool(serde_json::from_str(text)?)),
412 Some(b'n') => Ok(Value::Null),
413 _ => Ok(Value::Number(Number(String::from(text)))),
414 }
415}
416
417#[derive(Debug, Clone, PartialEq, Eq)]
419pub enum DecodeErrorKind {
420 UnknownProperty,
422 MissingProperty,
424 WrongType {
426 expected: &'static str,
428 },
429 WrongCardinality,
432 Empty,
434 BadNumber,
436 BadValue,
438 DuplicateChoice,
440 ResourceType,
442 UnknownElement,
444 UnexpectedText,
446 WrongRoot,
448 MalformedXml {
450 reason: String,
452 },
453}
454
455impl fmt::Display for DecodeErrorKind {
456 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
457 match self {
458 Self::UnknownProperty => f.write_str("unknown property"),
459 Self::MissingProperty => f.write_str("required property is missing"),
460 Self::WrongType { expected } => write!(f, "expected {expected}"),
461 Self::WrongCardinality => f.write_str("cardinality mismatch"),
462 Self::Empty => f.write_str("empty object or array"),
463 Self::BadNumber => f.write_str("number out of range"),
464 Self::BadValue => f.write_str("invalid value"),
465 Self::DuplicateChoice => f.write_str("more than one form of a choice element"),
466 Self::ResourceType => f.write_str("resourceType is missing or does not match"),
467 Self::UnknownElement => f.write_str("unknown element"),
468 Self::UnexpectedText => f.write_str("text where an element belongs"),
469 Self::WrongRoot => f.write_str("the root element is no resource of this version"),
470 Self::MalformedXml { reason } => write!(f, "malformed XML: {reason}"),
471 }
472 }
473}
474
475#[derive(Debug, Clone, PartialEq, Eq)]
477pub struct DecodeError {
478 pub path: String,
480 pub kind: DecodeErrorKind,
482}
483
484impl fmt::Display for DecodeError {
485 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
486 write!(f, "{}: {}", self.path, self.kind)
487 }
488}
489
490impl std::error::Error for DecodeError {}
491
492#[derive(Debug, Clone, Copy, PartialEq, Eq)]
496pub struct LexicalError {
497 pub type_code: &'static str,
499}
500
501impl fmt::Display for LexicalError {
502 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
503 write!(
504 f,
505 "the text is outside the lexical form of {}",
506 self.type_code
507 )
508 }
509}
510
511impl std::error::Error for LexicalError {}
512
513#[derive(Debug, Default, Clone)]
515pub struct Path {
516 segments: Vec<String>,
517 lenient: bool,
518}
519
520impl Path {
521 #[must_use]
523 pub fn root(root: &str) -> Self {
524 Self {
525 segments: vec![root.to_owned()],
526 lenient: false,
527 }
528 }
529
530 #[must_use]
542 pub fn lenient(root: &str) -> Self {
543 Self {
544 segments: vec![root.to_owned()],
545 lenient: true,
546 }
547 }
548
549 #[must_use]
551 pub const fn is_lenient(&self) -> bool {
552 self.lenient
553 }
554
555 #[must_use]
557 pub fn location(&self) -> String {
558 self.segments.join(".")
559 }
560
561 pub fn with<T, E>(
567 &mut self,
568 name: &str,
569 f: impl FnOnce(&mut Self) -> Result<T, E>,
570 ) -> Result<T, E> {
571 self.segments.push(name.to_owned());
572 let out = f(self);
573 self.segments.pop();
574 out
575 }
576
577 pub fn with_index<T, E>(
583 &mut self,
584 name: &str,
585 index: usize,
586 f: impl FnOnce(&mut Self) -> Result<T, E>,
587 ) -> Result<T, E> {
588 self.segments.push(format!("{name}[{index}]"));
589 let out = f(self);
590 self.segments.pop();
591 out
592 }
593
594 #[must_use]
596 pub fn error(&self, kind: DecodeErrorKind) -> DecodeError {
597 DecodeError {
598 path: self.location(),
599 kind,
600 }
601 }
602}
603
604pub trait Json: Sized {
606 fn to_json(&self) -> Result<Object, EncodeError>;
612
613 fn from_json(object: &Object, path: &mut Path) -> Result<Self, DecodeError>;
619}
620
621#[inline(never)]
632pub fn boxed<T: Json>(object: &Object, path: &mut Path) -> Result<Box<T>, DecodeError> {
633 Ok(Box::new(T::from_json(object, path)?))
634}
635
636pub trait Primitive: Sized {
638 fn value_json(&self) -> Result<Option<Value>, EncodeError>;
644
645 fn element_json(&self) -> Result<Option<Value>, EncodeError>;
651
652 fn from_json_parts(
658 value: Option<&Value>,
659 element: Option<&Value>,
660 path: &mut Path,
661 ) -> Result<Self, DecodeError>;
662
663 fn has_value(&self) -> bool;
665
666 fn has_element(&self) -> bool;
668
669 fn serialize_value<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
676
677 fn serialize_element<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
684}
685
686#[derive(Debug)]
691pub struct PrimitiveValue<'a, P: Primitive>(pub &'a P);
692
693impl<P: Primitive> serde::Serialize for PrimitiveValue<'_, P> {
694 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
695 self.0.serialize_value(serializer)
696 }
697}
698
699#[derive(Debug)]
701pub struct PrimitiveElement<'a, P: Primitive>(pub &'a P);
702
703impl<P: Primitive> serde::Serialize for PrimitiveElement<'_, P> {
704 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
705 self.0.serialize_element(serializer)
706 }
707}
708
709#[derive(Debug)]
712pub struct PrimitiveValues<'a, P: Primitive>(pub &'a [P]);
713
714impl<P: Primitive> serde::Serialize for PrimitiveValues<'_, P> {
715 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
716 let mut seq = serde::Serializer::serialize_seq(serializer, Some(self.0.len()))?;
717 for item in self.0 {
718 serde::ser::SerializeSeq::serialize_element(&mut seq, &PrimitiveValue(item))?;
719 }
720 serde::ser::SerializeSeq::end(seq)
721 }
722}
723
724#[derive(Debug)]
727pub struct PrimitiveElements<'a, P: Primitive>(pub &'a [P]);
728
729impl<P: Primitive> serde::Serialize for PrimitiveElements<'_, P> {
730 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
731 let mut seq = serde::Serializer::serialize_seq(serializer, Some(self.0.len()))?;
732 for item in self.0 {
733 serde::ser::SerializeSeq::serialize_element(&mut seq, &PrimitiveElement(item))?;
734 }
735 serde::ser::SerializeSeq::end(seq)
736 }
737}
738
739pub fn value_entry<M: serde::ser::SerializeMap, P: Primitive>(
745 map: &mut M,
746 key: &str,
747 primitive: &P,
748) -> Result<(), M::Error> {
749 if primitive.has_value() {
750 map.serialize_entry(key, &PrimitiveValue(primitive))?;
751 }
752 Ok(())
753}
754
755pub fn element_entry<M: serde::ser::SerializeMap, P: Primitive>(
762 map: &mut M,
763 key: &str,
764 primitive: &P,
765) -> Result<(), M::Error> {
766 if primitive.has_element() {
767 map.serialize_entry(key, &PrimitiveElement(primitive))?;
768 }
769 Ok(())
770}
771
772pub fn value_list_entry<M: serde::ser::SerializeMap, P: Primitive>(
783 map: &mut M,
784 key: &str,
785 items: &[P],
786) -> Result<(), M::Error> {
787 if items.iter().any(Primitive::has_value) {
788 map.serialize_entry(key, &PrimitiveValues(items))?;
789 }
790 Ok(())
791}
792
793pub fn element_list_entry<M: serde::ser::SerializeMap, P: Primitive>(
800 map: &mut M,
801 key: &str,
802 items: &[P],
803) -> Result<(), M::Error> {
804 if items.iter().any(Primitive::has_element) {
805 map.serialize_entry(key, &PrimitiveElements(items))?;
806 }
807 Ok(())
808}
809
810pub fn expect_object<'a>(value: &'a Value, path: &Path) -> Result<&'a Object, DecodeError> {
816 match value {
817 Value::Object(object) if object.is_empty() => Err(path.error(DecodeErrorKind::Empty)),
818 Value::Object(object) => Ok(object),
819 _ => Err(path.error(DecodeErrorKind::WrongType {
820 expected: "an object",
821 })),
822 }
823}
824
825pub fn expect_array<'a>(value: &'a Value, path: &Path) -> Result<&'a [Value], DecodeError> {
831 match value {
832 Value::Array(items) if items.is_empty() => Err(path.error(DecodeErrorKind::Empty)),
833 Value::Array(items) => Ok(items),
834 _ => Err(path.error(DecodeErrorKind::WrongType {
835 expected: "an array",
836 })),
837 }
838}
839
840pub fn expect_single<'a>(value: &'a Value, path: &Path) -> Result<&'a Value, DecodeError> {
846 match value {
847 Value::Array(_) => Err(path.error(DecodeErrorKind::WrongCardinality)),
848 other => Ok(other),
849 }
850}
851
852pub fn expect_string(value: &Value, path: &Path) -> Result<String, DecodeError> {
858 match value {
859 Value::String(s) => Ok(s.clone()),
860 _ => Err(path.error(DecodeErrorKind::WrongType {
861 expected: "a string",
862 })),
863 }
864}
865
866pub fn expect_bool(value: &Value, path: &Path) -> Result<bool, DecodeError> {
872 match value {
873 Value::Bool(b) => Ok(*b),
874 _ => Err(path.error(DecodeErrorKind::WrongType {
875 expected: "a boolean",
876 })),
877 }
878}
879
880pub fn expect_i32(value: &Value, path: &Path) -> Result<i32, DecodeError> {
886 match value {
887 Value::Number(n) => n
888 .as_i64()
889 .and_then(|i| i32::try_from(i).ok())
890 .ok_or_else(|| path.error(DecodeErrorKind::BadNumber)),
891 _ => Err(path.error(DecodeErrorKind::WrongType {
892 expected: "a number",
893 })),
894 }
895}
896
897pub fn expect_u32(value: &Value, min: u32, path: &Path) -> Result<u32, DecodeError> {
903 match value {
904 Value::Number(n) => n
905 .as_u64()
906 .and_then(|u| u32::try_from(u).ok())
907 .filter(|u| *u >= min)
908 .ok_or_else(|| path.error(DecodeErrorKind::BadNumber)),
909 _ => Err(path.error(DecodeErrorKind::WrongType {
910 expected: "a number",
911 })),
912 }
913}
914
915pub fn expect_i64_string(value: &Value, path: &Path) -> Result<i64, DecodeError> {
921 match value {
922 Value::String(s) => s
923 .parse()
924 .map_err(|_| path.error(DecodeErrorKind::BadNumber)),
925 _ => Err(path.error(DecodeErrorKind::WrongType {
926 expected: "a string holding an integer",
927 })),
928 }
929}
930
931pub fn expect_decimal(value: &Value, path: &Path) -> Result<String, DecodeError> {
937 match value {
938 Value::Number(n) => Ok(String::from(n.as_str())),
939 _ => Err(path.error(DecodeErrorKind::WrongType {
940 expected: "a number",
941 })),
942 }
943}
944
945pub fn decimal_value(text: &str, path: &Path) -> Result<Value, DecodeError> {
951 text.parse::<Number>()
952 .map(Value::Number)
953 .map_err(|_| path.error(DecodeErrorKind::BadValue))
954}
955
956pub type ValuePair<'a> = (Option<&'a Value>, Option<&'a Value>);
958
959pub fn pair_arrays<'a>(
966 values: Option<&'a Value>,
967 elements: Option<&'a Value>,
968 path: &Path,
969) -> Result<Vec<ValuePair<'a>>, DecodeError> {
970 let values = values.map(|v| expect_array(v, path)).transpose()?;
971 let elements = elements.map(|v| expect_array(v, path)).transpose()?;
972 let len = match (values, elements) {
973 (Some(v), Some(e)) if v.len() != e.len() => {
974 return Err(path.error(DecodeErrorKind::WrongCardinality));
975 }
976 (Some(v), _) => v.len(),
977 (None, Some(e)) => e.len(),
978 (None, None) => 0,
979 };
980 Ok((0..len)
981 .map(|i| {
982 let value = values.and_then(|v| v.get(i)).filter(|v| !v.is_null());
983 let element = elements.and_then(|e| e.get(i)).filter(|e| !e.is_null());
984 (value, element)
985 })
986 .collect())
987}
988
989pub fn primitive_arrays<P: Primitive>(
999 items: &[P],
1000) -> Result<(Option<Value>, Option<Value>), EncodeError> {
1001 let mut values = Vec::with_capacity(items.len());
1002 let mut elements = Vec::with_capacity(items.len());
1003 for item in items {
1004 values.push(item.value_json()?.unwrap_or(Value::Null));
1005 elements.push(item.element_json()?.unwrap_or(Value::Null));
1006 }
1007 let any_value = values.iter().any(|v| !v.is_null());
1008 let any_element = elements.iter().any(|e| !e.is_null());
1009 Ok((
1010 any_value.then_some(Value::Array(values)),
1011 any_element.then_some(Value::Array(elements)),
1012 ))
1013}
1014
1015#[derive(Debug, Clone, PartialEq, Eq)]
1017pub enum EncodeError {
1018 BadDecimal {
1020 text: String,
1022 },
1023 UnknownResourceBody,
1025 Xml {
1027 reason: String,
1029 },
1030}
1031
1032impl fmt::Display for EncodeError {
1033 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1034 match self {
1035 Self::BadDecimal { text } => write!(f, "decimal {text:?} is not a JSON number"),
1036 Self::UnknownResourceBody => f.write_str("an unknown resource's body is not an object"),
1037 Self::Xml { reason } => write!(f, "no XML form: {reason}"),
1038 }
1039 }
1040}
1041
1042impl std::error::Error for EncodeError {}
1043
1044#[derive(Debug, Default)]
1046pub struct ChoiceSlot<'a> {
1047 pub suffix: Option<&'static str>,
1049 pub value: Option<&'a Value>,
1051 pub element: Option<&'a Value>,
1053}
1054
1055impl<'a> ChoiceSlot<'a> {
1056 fn claim(&mut self, suffix: &'static str, path: &Path) -> Result<(), DecodeError> {
1057 match self.suffix {
1058 Some(seen) if seen != suffix => Err(path.error(DecodeErrorKind::DuplicateChoice)),
1059 _ => {
1060 self.suffix = Some(suffix);
1061 Ok(())
1062 }
1063 }
1064 }
1065
1066 pub fn value(
1072 &mut self,
1073 suffix: &'static str,
1074 value: &'a Value,
1075 path: &Path,
1076 ) -> Result<(), DecodeError> {
1077 self.claim(suffix, path)?;
1078 self.value = Some(value);
1079 Ok(())
1080 }
1081
1082 pub fn element(
1088 &mut self,
1089 suffix: &'static str,
1090 element: &'a Value,
1091 path: &Path,
1092 ) -> Result<(), DecodeError> {
1093 self.claim(suffix, path)?;
1094 self.element = Some(element);
1095 Ok(())
1096 }
1097}
1098
1099pub fn resource_type<'a>(object: &'a Object, path: &Path) -> Result<&'a str, DecodeError> {
1105 match object.get("resourceType") {
1106 Some(Value::String(name)) => Ok(name),
1107 _ => Err(path.error(DecodeErrorKind::ResourceType)),
1108 }
1109}