musli_json/de/
sequence_decoder.rs1use core::mem;
2
3use musli::de::{Decoder, SequenceDecoder, SizeHint};
4use musli::Context;
5
6use crate::parser::{Parser, Token};
7
8use super::JsonDecoder;
9
10#[must_use = "Must call skip_sequence_remaining"]
11pub(crate) struct JsonSequenceDecoder<'a, P, C: ?Sized> {
12 cx: &'a C,
13 len: Option<usize>,
14 first: bool,
15 parser: P,
16 finalized: bool,
17}
18
19impl<'a, 'de, P, C> JsonSequenceDecoder<'a, P, C>
20where
21 P: Parser<'de>,
22 C: ?Sized + Context,
23{
24 #[inline]
25 pub(super) fn new(cx: &'a C, len: Option<usize>, mut parser: P) -> Result<Self, C::Error> {
26 let actual = parser.peek(cx)?;
27
28 if !matches!(actual, Token::OpenBracket) {
29 return Err(cx.message(format_args!("Expected opening bracket, was {actual}")));
30 }
31
32 parser.skip(cx, 1)?;
33
34 Ok(Self {
35 cx,
36 len,
37 first: true,
38 parser,
39 finalized: false,
40 })
41 }
42
43 fn parse_next_value(&mut self) -> Result<bool, C::Error> {
44 let first = mem::take(&mut self.first);
45
46 loop {
47 let token = self.parser.peek(self.cx)?;
48
49 if token.is_value() {
50 return Ok(true);
51 }
52
53 match token {
54 Token::Comma if !first => {
55 self.parser.skip(self.cx, 1)?;
56 }
57 Token::CloseBracket => {
58 return Ok(false);
59 }
60 _ => {
61 return Err(self.cx.message(format_args!(
62 "Expected value or closing bracket `]`, but found {token}"
63 )));
64 }
65 }
66 }
67 }
68
69 #[inline]
70 pub(super) fn skip_sequence_remaining(mut self) -> Result<(), C::Error> {
71 if self.finalized {
72 return Ok(());
73 }
74
75 while let Some(decoder) = SequenceDecoder::try_decode_next(&mut self)? {
76 decoder.skip()?;
77 }
78
79 let actual = self.parser.peek(self.cx)?;
80
81 if !matches!(actual, Token::CloseBracket) {
82 return Err(self
83 .cx
84 .message(format_args!("Expected closing bracket, was {actual}")));
85 }
86
87 self.parser.skip(self.cx, 1)?;
88 self.finalized = true;
89 Ok(())
90 }
91}
92
93impl<'a, 'de, P, C> SequenceDecoder<'de> for JsonSequenceDecoder<'a, P, C>
94where
95 P: Parser<'de>,
96 C: ?Sized + Context,
97{
98 type Cx = C;
99 type DecodeNext<'this> = JsonDecoder<'a, P::Mut<'this>, C>
100 where
101 Self: 'this;
102
103 #[inline]
104 fn size_hint(&self) -> SizeHint {
105 SizeHint::from(self.len)
106 }
107
108 #[inline]
109 fn try_decode_next(&mut self) -> Result<Option<Self::DecodeNext<'_>>, C::Error> {
110 if !self.parse_next_value()? {
111 return Ok(None);
112 }
113
114 Ok(Some(JsonDecoder::new(self.cx, self.parser.borrow_mut())))
115 }
116
117 #[inline]
118 fn decode_next(&mut self) -> Result<Self::DecodeNext<'_>, C::Error> {
119 if !self.parse_next_value()? {
120 return Err(self.cx.message(format_args!("Encountered short array")));
121 }
122
123 Ok(JsonDecoder::new(self.cx, self.parser.borrow_mut()))
124 }
125}