1#![deny(missing_docs)]
10#![no_std]
11#![cfg_attr(doc_cfg, feature(doc_cfg))]
12
13#[cfg(feature = "alloc")]
14extern crate alloc as rust_alloc;
15
16#[cfg(feature = "std")]
17extern crate std;
18
19mod expecting;
20mod impls;
21mod internal;
22mod never;
23
24pub mod alloc;
25#[doc(inline)]
26pub use self::alloc::Allocator;
27
28mod context;
29#[doc(inline)]
30pub use self::context::Context;
31
32pub mod de;
33#[doc(inline)]
34pub use self::de::{decoder, Decode, Decoder};
35
36pub mod en;
37#[doc(inline)]
38pub use self::en::{encoder, Encode, Encoder};
39
40pub mod hint;
41pub mod mode;
42
43#[doc(hidden)]
44pub use musli_macros as __macros;
45
46#[doc(hidden)]
50pub mod __priv {
51 use core::marker::PhantomData;
52
53 pub use crate::alloc::Allocator;
54 use crate::alloc::String;
55 pub use crate::context::Context;
56 pub use crate::de::{
57 AsDecoder, Decode, DecodeBytes, DecodePacked, DecodeTrace, Decoder, EntryDecoder,
58 MapDecoder, SequenceDecoder, TryFastDecode, VariantDecoder,
59 };
60 pub use crate::en::{
61 Encode, EncodeBytes, EncodePacked, EncodeTrace, Encoder, EntryEncoder, MapEncoder,
62 SequenceEncoder, TryFastEncode, VariantEncoder,
63 };
64 pub use crate::hint::MapHint;
65 pub use crate::never::Never;
66
67 pub use ::core::fmt;
68 pub use ::core::mem::{needs_drop, offset_of, size_of};
69 pub use ::core::option::Option;
70 pub use ::core::result::Result;
71
72 #[inline]
73 pub fn default<T>() -> T
74 where
75 T: ::core::default::Default,
76 {
77 ::core::default::Default::default()
78 }
79
80 #[inline]
82 pub fn skip<'de, D>(decoder: D) -> Result<bool, D::Error>
83 where
84 D: Decoder<'de>,
85 {
86 Ok(decoder.try_skip()?.is_unsupported())
87 }
88
89 #[inline]
91 pub fn skip_field<'de, D>(decoder: D) -> Result<bool, D::Error>
92 where
93 D: EntryDecoder<'de>,
94 {
95 skip(decoder.decode_value()?)
96 }
97
98 #[inline]
102 pub fn collect_string<C>(
103 cx: C,
104 value: impl fmt::Display,
105 ) -> Result<String<C::Allocator>, C::Error>
106 where
107 C: Context,
108 {
109 match crate::alloc::collect_string(cx.alloc(), value) {
110 Ok(string) => Ok(string),
111 Err(error) => Err(cx.message(error)),
112 }
113 }
114
115 #[inline]
117 pub fn map_hint<M>(encode: &(impl Encode<M> + ?Sized)) -> impl MapHint + '_
118 where
119 M: 'static,
120 {
121 EncodeMapHint {
122 encode,
123 _marker: PhantomData,
124 }
125 }
126
127 pub(crate) struct EncodeMapHint<'a, T, M>
128 where
129 T: ?Sized,
130 {
131 encode: &'a T,
132 _marker: PhantomData<M>,
133 }
134
135 impl<T, M> MapHint for EncodeMapHint<'_, T, M>
136 where
137 T: ?Sized + Encode<M>,
138 {
139 #[inline]
140 fn get(self) -> Option<usize> {
141 self.encode.size_hint()
142 }
143 }
144
145 pub mod m {
147 use core::fmt;
148
149 use crate::Context;
150
151 #[inline]
153 pub fn invalid_variant_tag<C>(
154 cx: C,
155 type_name: &'static str,
156 tag: impl fmt::Debug,
157 ) -> C::Error
158 where
159 C: Context,
160 {
161 cx.message(format_args!(
162 "Type {type_name} received invalid variant tag {tag:?}"
163 ))
164 }
165
166 #[inline]
168 pub fn expected_tag<C>(cx: C, type_name: &'static str, tag: impl fmt::Debug) -> C::Error
169 where
170 C: Context,
171 {
172 cx.message(format_args!("Type {type_name} expected tag {tag:?}"))
173 }
174
175 #[inline]
177 pub fn uninhabitable<C>(cx: C, type_name: &'static str) -> C::Error
178 where
179 C: Context,
180 {
181 cx.message(format_args!(
182 "Type {type_name} cannot be decoded since it's uninhabitable"
183 ))
184 }
185
186 #[inline]
188 pub fn invalid_field_tag<C>(
189 cx: C,
190 type_name: &'static str,
191 tag: impl fmt::Debug,
192 ) -> C::Error
193 where
194 C: Context,
195 {
196 cx.message(format_args!(
197 "Type {type_name} is missing invalid field tag {tag:?}"
198 ))
199 }
200
201 #[inline]
203 pub fn expected_field_adjacent<C>(
204 cx: C,
205 type_name: &'static str,
206 tag: impl fmt::Debug,
207 content: impl fmt::Debug,
208 ) -> C::Error
209 where
210 C: Context,
211 {
212 cx.message(format_args!(
213 "Type {type_name} expected adjacent field {tag:?} or {content:?}"
214 ))
215 }
216
217 #[inline]
219 pub fn missing_adjacent_tag<C>(
220 cx: C,
221 type_name: &'static str,
222 tag: impl fmt::Debug,
223 ) -> C::Error
224 where
225 C: Context,
226 {
227 cx.message(format_args!(
228 "Type {type_name} is missing adjacent tag {tag:?}"
229 ))
230 }
231
232 #[inline]
234 pub fn invalid_field_string_tag<C>(
235 cx: C,
236 type_name: &'static str,
237 field: impl fmt::Debug,
238 ) -> C::Error
239 where
240 C: Context,
241 {
242 cx.message(format_args!(
243 "Type {type_name} received invalid field tag {field:?}"
244 ))
245 }
246
247 #[inline]
249 pub fn missing_variant_field<C>(
250 cx: C,
251 type_name: &'static str,
252 tag: impl fmt::Debug,
253 ) -> C::Error
254 where
255 C: Context,
256 {
257 cx.message(format_args!(
258 "Type {type_name} is missing variant field {tag:?}"
259 ))
260 }
261
262 #[inline]
264 pub fn invalid_variant_field_tag<C>(
265 cx: C,
266 type_name: &'static str,
267 variant: impl fmt::Debug,
268 tag: impl fmt::Debug,
269 ) -> C::Error
270 where
271 C: Context,
272 {
273 cx.message(format_args!(
274 "Type {type_name} received invalid variant field tag {tag:?} for variant {variant:?}",
275 ))
276 }
277
278 #[inline]
280 pub fn untagged_mismatch<C>(cx: C, type_name: &'static str) -> C::Error
281 where
282 C: Context,
283 {
284 cx.message(format_args!("No variant of {type_name} could be decoded"))
285 }
286 }
287}