musli_core/
lib.rs

1//! [<img alt="github" src="https://img.shields.io/badge/github-udoprog/musli-8da0cb?style=for-the-badge&logo=github" height="20">](https://github.com/udoprog/musli)
2//! [<img alt="crates.io" src="https://img.shields.io/crates/v/musli-core.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/musli-core)
3//! [<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-musli--core-66c2a5?style=for-the-badge&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/musli-core)
4//!
5//! Core traits for [Müsli].
6//!
7//! [Müsli]: https://docs.rs/musli
8
9#![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
19pub mod alloc;
20
21mod context;
22#[doc(inline)]
23pub use self::context::Context;
24
25pub mod de;
26#[doc(inline)]
27pub use self::de::{Decode, Decoder};
28
29pub mod en;
30#[doc(inline)]
31pub use self::en::{Encode, Encoder};
32
33pub mod hint;
34pub mod mode;
35pub mod no_std;
36
37mod expecting;
38mod impls;
39mod internal;
40mod never;
41
42/// This is an attribute macro that must be used when implementing a
43/// [`Encoder`].
44///
45/// It is required to use because a [`Encoder`] implementation might introduce
46/// new associated types in the future, and this [not yet supported] on a
47/// language level in Rust. So this attribute macro polyfills any missing types
48/// automatically.
49///
50/// Note that using derives directly from `musli_core` requires you to use the
51/// `#[musli_core::encoder(crate = musli_core)]` attribute.
52///
53/// [not yet supported]: https://rust-lang.github.io/rfcs/2532-associated-type-defaults.html
54///
55/// # Examples
56///
57/// ```
58/// use std::fmt;
59///
60/// use musli_core::Context;
61/// use musli_core::en::{Encoder, Encode};
62///
63/// struct MyEncoder<'a, C: ?Sized> {
64///     value: &'a mut Option<u32>,
65///     cx: &'a C,
66/// }
67///
68/// #[musli_core::encoder(crate = musli_core)]
69/// impl<C: ?Sized + Context> Encoder for MyEncoder<'_, C> {
70///     type Cx = C;
71///     type Ok = ();
72///
73///     fn cx(&self) -> &C {
74///         self.cx
75///     }
76///
77///     fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78///         write!(f, "32-bit unsigned integers")
79///     }
80///
81///     fn encode<T>(self, value: T) -> Result<Self::Ok, C::Error>
82///     where
83///         T: Encode<Self::Mode>,
84///     {
85///         value.encode(self.cx, self)
86///     }
87///
88///     fn encode_u32(self, value: u32) -> Result<(), Self::Error> {
89///         *self.value = Some(value);
90///         Ok(())
91///     }
92/// }
93/// ```
94#[doc(inline)]
95pub use musli_macros::encoder;
96
97/// This is an attribute macro that must be used when implementing a
98/// [`Decoder`].
99///
100/// It is required to use because a [`Decoder`] implementation might introduce
101/// new associated types in the future, and this is [not yet supported] on a
102/// language level in Rust. So this attribute macro polyfills any missing types
103/// automatically.
104///
105/// Note that using derives directly from `musli_core` requires you to use the
106/// `#[musli_core::decoder(crate = musli_core)]` attribute.
107///
108/// [not yet supported]: https://rust-lang.github.io/rfcs/2532-associated-type-defaults.html
109///
110/// # Examples
111///
112/// ```
113/// use std::fmt;
114///
115/// use musli_core::Context;
116/// use musli_core::de::{Decoder, Decode};
117///
118/// struct MyDecoder<'a, C: ?Sized> {
119///     cx: &'a C,
120/// }
121///
122/// #[musli_core::decoder(crate = musli_core)]
123/// impl<'de, C: ?Sized + Context> Decoder<'de> for MyDecoder<'_, C> {
124///     type Cx = C;
125///
126///     fn cx(&self) -> &C {
127///         self.cx
128///     }
129///
130///     fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131///         write!(f, "32-bit unsigned integers")
132///     }
133///
134///     fn decode_u32(self) -> Result<u32, Self::Error> {
135///         Ok(42)
136///     }
137/// }
138/// ```
139#[doc(inline)]
140pub use musli_macros::decoder;
141
142/// This is an attribute macro that must be used when implementing a
143/// [`Visitor`].
144///
145/// It is required to use because a [`Visitor`] implementation might introduce
146/// new associated types in the future, and this is [not yet supported] on a
147/// language level in Rust. So this attribute macro polyfills any missing types
148/// automatically.
149///
150/// Note that using derives directly from `musli_core` requires you to use the
151/// `#[musli_core::visitor(crate = musli_core)]` attribute.
152///
153/// [not yet supported]: https://rust-lang.github.io/rfcs/2532-associated-type-defaults.html
154/// [`Visitor`]: crate::de::Visitor
155///
156/// # Examples
157///
158/// ```
159/// use std::fmt;
160///
161/// use musli_core::Context;
162/// use musli_core::de::Visitor;
163///
164/// struct AnyVisitor;
165///
166/// #[musli_core::visitor(crate = musli_core)]
167/// impl<'de, C: ?Sized + Context> Visitor<'de, C> for AnyVisitor {
168///     type Ok = ();
169///
170///     #[inline]
171///     fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172///         write!(
173///             f,
174///             "value that can be decoded into dynamic container"
175///         )
176///     }
177/// }
178/// ```
179#[doc(inline)]
180pub use musli_macros::visitor;
181
182/// Internal implementation details of musli.
183///
184/// Using these directly is not supported.
185#[doc(hidden)]
186pub mod __priv {
187    use crate::context::Context;
188    use crate::de::{Decoder, EntryDecoder};
189
190    pub use ::core::fmt;
191    pub use ::core::option::Option;
192    pub use ::core::result::Result;
193
194    pub use crate::never::Never;
195
196    #[inline(always)]
197    pub fn default<T>() -> T
198    where
199        T: ::core::default::Default,
200    {
201        ::core::default::Default::default()
202    }
203
204    /// Note that this returns `true` if skipping was unsupported.
205    #[inline(always)]
206    pub fn skip<'de, D>(decoder: D) -> Result<bool, D::Error>
207    where
208        D: Decoder<'de>,
209    {
210        Ok(decoder.try_skip()?.is_unsupported())
211    }
212
213    /// Note that this returns `true` if skipping was unsupported.
214    #[inline(always)]
215    pub fn skip_field<'de, D>(decoder: D) -> Result<bool, <D::Cx as Context>::Error>
216    where
217        D: EntryDecoder<'de>,
218    {
219        skip(decoder.decode_value()?)
220    }
221
222    pub use Option::{None, Some};
223    pub use Result::{Err, Ok};
224}