1use core::fmt;
2
3use musli::de::{Decode, DecodeUnsized, Decoder, SizeHint, Skip, ValueVisitor, Visitor};
4use musli::Context;
5
6use crate::parser::{Parser, Token};
7
8use super::{JsonDecoder, KeySignedVisitor, KeyUnsignedVisitor, StringReference};
9
10pub(crate) struct JsonKeyDecoder<'a, P, C: ?Sized> {
12 cx: &'a C,
13 parser: P,
14}
15
16impl<'a, 'de, P, C> JsonKeyDecoder<'a, P, C>
17where
18 P: Parser<'de>,
19 C: ?Sized + Context,
20{
21 #[inline]
23 pub(crate) fn new(cx: &'a C, parser: P) -> Self {
24 Self { cx, parser }
25 }
26
27 #[inline]
28 fn decode_escaped_bytes<V>(mut self, visitor: V) -> Result<V::Ok, C::Error>
29 where
30 V: ValueVisitor<'de, C, [u8]>,
31 {
32 let Some(mut scratch) = self.cx.alloc() else {
33 return Err(self.cx.message("Failed to allocate scratch buffer"));
34 };
35
36 match self.parser.parse_string(self.cx, true, &mut scratch)? {
37 StringReference::Borrowed(string) => visitor.visit_borrowed(self.cx, string.as_bytes()),
38 StringReference::Scratch(string) => visitor.visit_ref(self.cx, string.as_bytes()),
39 }
40 }
41}
42
43#[musli::decoder]
44impl<'a, 'de, P, C> Decoder<'de> for JsonKeyDecoder<'a, P, C>
45where
46 P: Parser<'de>,
47 C: ?Sized + Context,
48{
49 type Cx = C;
50 type Error = C::Error;
51 type Mode = C::Mode;
52 type WithContext<'this, U> = JsonKeyDecoder<'this, P, U> where U: 'this + Context;
53
54 #[inline]
55 fn cx(&self) -> &Self::Cx {
56 self.cx
57 }
58
59 #[inline]
60 fn with_context<U>(self, cx: &U) -> Result<Self::WithContext<'_, U>, C::Error>
61 where
62 U: Context,
63 {
64 Ok(JsonKeyDecoder::new(cx, self.parser))
65 }
66
67 #[inline]
68 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 write!(f, "value that can be decoded from a object key")
70 }
71
72 #[inline]
73 fn decode<T>(self) -> Result<T, Self::Error>
74 where
75 T: Decode<'de, Self::Mode>,
76 {
77 self.cx.decode(self)
78 }
79
80 #[inline]
81 fn decode_unsized<T, F, O>(self, f: F) -> Result<O, Self::Error>
82 where
83 T: ?Sized + DecodeUnsized<'de, Self::Mode>,
84 F: FnOnce(&T) -> Result<O, Self::Error>,
85 {
86 self.cx.decode_unsized(self, f)
87 }
88
89 #[inline]
90 fn skip(self) -> Result<(), C::Error> {
91 JsonDecoder::new(self.cx, self.parser).skip()
92 }
93
94 #[inline]
95 fn try_skip(self) -> Result<Skip, C::Error> {
96 self.skip()?;
97 Ok(Skip::Skipped)
98 }
99
100 #[inline]
101 fn decode_u8(self) -> Result<u8, C::Error> {
102 self.decode_escaped_bytes(KeyUnsignedVisitor::new())
103 }
104
105 #[inline]
106 fn decode_u16(self) -> Result<u16, C::Error> {
107 self.decode_escaped_bytes(KeyUnsignedVisitor::new())
108 }
109
110 #[inline]
111 fn decode_u32(self) -> Result<u32, C::Error> {
112 self.decode_escaped_bytes(KeyUnsignedVisitor::new())
113 }
114
115 #[inline]
116 fn decode_u64(self) -> Result<u64, C::Error> {
117 self.decode_escaped_bytes(KeyUnsignedVisitor::new())
118 }
119
120 #[inline]
121 fn decode_u128(self) -> Result<u128, C::Error> {
122 self.decode_escaped_bytes(KeyUnsignedVisitor::new())
123 }
124
125 #[inline]
126 fn decode_i8(self) -> Result<i8, C::Error> {
127 self.decode_escaped_bytes(KeySignedVisitor::new())
128 }
129
130 #[inline]
131 fn decode_i16(self) -> Result<i16, C::Error> {
132 self.decode_escaped_bytes(KeySignedVisitor::new())
133 }
134
135 #[inline]
136 fn decode_i32(self) -> Result<i32, C::Error> {
137 self.decode_escaped_bytes(KeySignedVisitor::new())
138 }
139
140 #[inline]
141 fn decode_i64(self) -> Result<i64, C::Error> {
142 self.decode_escaped_bytes(KeySignedVisitor::new())
143 }
144
145 #[inline]
146 fn decode_i128(self) -> Result<i128, C::Error> {
147 self.decode_escaped_bytes(KeySignedVisitor::new())
148 }
149
150 #[inline]
151 fn decode_usize(self) -> Result<usize, C::Error> {
152 self.decode_escaped_bytes(KeyUnsignedVisitor::new())
153 }
154
155 #[inline]
156 fn decode_isize(self) -> Result<isize, C::Error> {
157 self.decode_escaped_bytes(KeySignedVisitor::new())
158 }
159
160 #[inline]
161 fn decode_string<V>(self, visitor: V) -> Result<V::Ok, C::Error>
162 where
163 V: ValueVisitor<'de, C, str>,
164 {
165 JsonDecoder::new(self.cx, self.parser).decode_string(visitor)
166 }
167
168 #[inline]
169 fn decode_any<V>(mut self, visitor: V) -> Result<V::Ok, C::Error>
170 where
171 V: Visitor<'de, C>,
172 {
173 match self.parser.peek(self.cx)? {
174 Token::String => {
175 let visitor = visitor.visit_string(self.cx, SizeHint::Any)?;
176 self.decode_string(visitor)
177 }
178 Token::Number => {
179 let visitor = visitor.visit_number(self.cx)?;
180 self.decode_number(visitor)
181 }
182 token => Err(self
183 .cx
184 .message(format_args!("Unsupported key type {token:?}"))),
185 }
186 }
187}