musli_json/de/
sequence_decoder.rs

1use 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}