musli_json/de/
variant_decoder.rs1use musli::de::VariantDecoder;
2use musli::Context;
3
4use crate::parser::{Parser, Token};
5
6use super::{JsonDecoder, JsonKeyDecoder};
7
8pub(crate) struct JsonVariantDecoder<'a, P, C: ?Sized> {
9 cx: &'a C,
10 parser: P,
11}
12
13impl<'a, 'de, P, C> JsonVariantDecoder<'a, P, C>
14where
15 P: Parser<'de>,
16 C: ?Sized + Context,
17{
18 #[inline]
19 pub(super) fn new(cx: &'a C, mut parser: P) -> Result<Self, C::Error> {
20 let actual = parser.peek(cx)?;
21
22 if !matches!(actual, Token::OpenBrace) {
23 return Err(cx.message(format_args!("Expected open brace, was {actual}")));
24 }
25
26 parser.skip(cx, 1)?;
27 Ok(Self { cx, parser })
28 }
29
30 #[inline]
31 pub(super) fn end(mut self) -> Result<(), C::Error> {
32 let actual = self.parser.peek(self.cx)?;
33
34 if !matches!(actual, Token::CloseBrace) {
35 return Err(self.cx.message(format_args!(
36 "Expected closing brace for variant, was {actual}"
37 )));
38 }
39
40 self.parser.skip(self.cx, 1)?;
41 Ok(())
42 }
43}
44
45impl<'a, 'de, P, C> VariantDecoder<'de> for JsonVariantDecoder<'a, P, C>
46where
47 P: Parser<'de>,
48 C: ?Sized + Context,
49{
50 type Cx = C;
51 type DecodeTag<'this> = JsonKeyDecoder<'a, P::Mut<'this>, C>
52 where
53 Self: 'this;
54 type DecodeValue<'this> = JsonDecoder<'a, P::Mut<'this>, C> where Self: 'this;
55
56 #[inline]
57 fn decode_tag(&mut self) -> Result<Self::DecodeTag<'_>, C::Error> {
58 Ok(JsonKeyDecoder::new(self.cx, self.parser.borrow_mut()))
59 }
60
61 #[inline]
62 fn decode_value(&mut self) -> Result<Self::DecodeValue<'_>, C::Error> {
63 let actual = self.parser.peek(self.cx)?;
64
65 if !matches!(actual, Token::Colon) {
66 return Err(self
67 .cx
68 .message(format_args!("Expected colon, was {actual}")));
69 }
70
71 self.parser.skip(self.cx, 1)?;
72 Ok(JsonDecoder::new(self.cx, self.parser.borrow_mut()))
73 }
74}