axum_codec/
decode.rs

1use crate::{Codec, CodecRejection, ContentType};
2
3crate::macros::__private_decode_trait! {
4	/// Decoder trait for deserializing bytes into all supported formats.
5	///
6	/// Note that feature flags affect this trait differently than normal. In this case,
7	/// feature flags further restrict the trait instead of being additive. This may change
8	/// in the future.
9}
10
11#[cfg(feature = "serde")]
12impl<'b, T> Codec<T>
13where
14	T: serde::de::Deserialize<'b>,
15{
16	/// Attempts to deserialize the given bytes as [JSON](https://www.json.org).
17	///
18	/// # Errors
19	///
20	/// See [`serde_json::from_slice`].
21	#[cfg(feature = "json")]
22	#[inline]
23	pub fn from_json(bytes: &'b [u8]) -> Result<Self, serde_json::Error> {
24		serde_json::from_slice(bytes).map(Self)
25	}
26
27	/// Attempts to deserialize the given bytes as [URL-encoded form data](https://url.spec.whatwg.org/#urlencoded-parsing).
28	///
29	/// # Errors
30	///
31	/// See [`serde_urlencoded::from_bytes`].
32	#[cfg(feature = "form")]
33	#[inline]
34	pub fn from_form(bytes: &'b [u8]) -> Result<Self, serde_urlencoded::de::Error> {
35		serde_urlencoded::from_bytes(bytes).map(Self)
36	}
37
38	/// Attempts to deserialize the given bytes as [MessagePack](https://msgpack.org).
39	/// Does not perform any validation if the `validator` feature is enabled. For
40	/// validation, use [`Self::from_bytes`].
41	///
42	/// # Errors
43	///
44	/// See [`rmp_serde::from_slice`].
45	#[cfg(feature = "msgpack")]
46	#[inline]
47	pub fn from_msgpack(bytes: &'b [u8]) -> Result<Self, rmp_serde::decode::Error> {
48		let mut deserializer = rmp_serde::Deserializer::new(bytes).with_human_readable();
49
50		serde::Deserialize::deserialize(&mut deserializer).map(Self)
51	}
52
53	/// Attemps to deserialize the given bytes as [CBOR](https://cbor.io).
54	/// Does not perform any validation if the `validator` feature is enabled. For
55	/// validation, use [`Self::from_bytes`].
56	///
57	/// # Errors
58	///
59	/// See [`ciborium::from_slice`].
60	#[cfg(feature = "cbor")]
61	#[inline]
62	pub fn from_cbor(bytes: &'b [u8]) -> Result<Self, ciborium::de::Error<std::io::Error>> {
63		ciborium::from_reader(bytes).map(Self)
64	}
65
66	/// Attempts to deserialize the given text as [YAML](https://yaml.org).
67	/// Does not perform any validation if the `validator` feature is enabled. For
68	/// validation, use [`Self::from_bytes`].
69	///
70	/// # Errors
71	///
72	/// See [`serde_yaml::from_slice`].
73	#[cfg(feature = "yaml")]
74	#[inline]
75	pub fn from_yaml(text: &'b str) -> Result<Self, serde_yaml::Error> {
76		serde_yaml::from_str(text).map(Self)
77	}
78
79	/// Attempts to deserialize the given text as [TOML](https://toml.io).
80	/// Does not perform any validation if the `validator` feature is enabled. For
81	/// validation, use [`Self::from_bytes`].
82	///
83	/// # Errors
84	///
85	/// See [`toml::from_str`].
86	#[cfg(feature = "toml")]
87	#[inline]
88	pub fn from_toml(text: &'b str) -> Result<Self, toml::de::Error> {
89		toml::from_str(text).map(Self)
90	}
91}
92
93impl<'b, T> Codec<T> {
94	/// Attempts to deserialize the given bytes as [Bincode](https://github.com/bincode-org/bincode).
95	/// Does not perform any validation if the `validator` feature is enabled. For
96	/// validation, use [`Self::from_bytes`].
97	///
98	/// # Errors
99	///
100	/// See [`bincode::decode_from_slice`].
101	#[cfg(feature = "bincode")]
102	#[inline]
103	pub fn from_bincode(bytes: &'b [u8]) -> Result<Self, bincode::error::DecodeError>
104	where
105		T: bincode::BorrowDecode<'b, ()>,
106	{
107		bincode::borrow_decode_from_slice(bytes, bincode::config::standard()).map(|t| Self(t.0))
108	}
109
110	/// Attempts to deserialize the given bytes as [Bitcode](https://github.com/SoftbearStudios/bitcode).
111	/// Does not perform any validation if the `validator` feature is enabled. For
112	/// validation, use [`Self::from_bytes`].
113	///
114	/// # Errors
115	///
116	/// See [`bitcode::decode`].
117	#[cfg(feature = "bitcode")]
118	#[inline]
119	pub fn from_bitcode(bytes: &'b [u8]) -> Result<Self, bitcode::Error>
120	where
121		T: bitcode::Decode<'b>,
122	{
123		bitcode::decode(bytes).map(Self)
124	}
125
126	/// Attempts to deserialize the given bytes as the specified [`ContentType`].
127	///
128	/// # Errors
129	///
130	/// See [`CodecRejection`].
131	pub fn from_bytes(bytes: &'b [u8], content_type: ContentType) -> Result<Self, CodecRejection>
132	where
133		T: CodecDecode<'b>,
134	{
135		let codec = match content_type {
136			#[cfg(feature = "json")]
137			ContentType::Json => Self::from_json(bytes)?,
138			#[cfg(feature = "form")]
139			ContentType::Form => Self::from_form(bytes)?,
140			#[cfg(feature = "msgpack")]
141			ContentType::MsgPack => Self::from_msgpack(bytes)?,
142			#[cfg(feature = "bincode")]
143			ContentType::Bincode => Self::from_bincode(bytes)?,
144			#[cfg(feature = "bitcode")]
145			ContentType::Bitcode => Self::from_bitcode(bytes)?,
146			#[cfg(feature = "cbor")]
147			ContentType::Cbor => Self::from_cbor(bytes)?,
148			#[cfg(feature = "yaml")]
149			ContentType::Yaml => Self::from_yaml(core::str::from_utf8(bytes)?)?,
150			#[cfg(feature = "toml")]
151			ContentType::Toml => Self::from_toml(core::str::from_utf8(bytes)?)?,
152		};
153
154		#[cfg(feature = "validator")]
155		validator::Validate::validate(&codec)?;
156
157		Ok(codec)
158	}
159}