1use crate::structure::IntoJsonSpec;
9use crate::{Body, Error, Identifier, Result};
10use serde::de::value::StringDeserializer;
11use serde::de::{self, Deserializer as _, IntoDeserializer};
12use serde::forward_to_deserialize_any;
13use std::fmt;
14use std::marker::PhantomData;
15
16pub struct Deserializer {
18 body: Body,
19}
20
21impl Deserializer {
22 pub fn from_str(input: &str) -> Result<Self> {
30 let body: Body = input.parse()?;
31 Ok(Deserializer { body })
32 }
33
34 pub fn from_body(body: Body) -> Self {
36 Self { body }
37 }
38}
39
40pub fn from_str<'de, T>(s: &'de str) -> Result<T>
91where
92 T: de::Deserialize<'de>,
93{
94 let deserializer = Deserializer::from_str(s)?;
95 T::deserialize(deserializer)
96}
97
98pub fn from_reader<T, R>(mut reader: R) -> Result<T>
143where
144 T: de::DeserializeOwned,
145 R: std::io::Read,
146{
147 let mut s = String::new();
148 reader.read_to_string(&mut s)?;
149
150 from_str(&s)
151}
152
153pub fn from_slice<'de, T>(buf: &'de [u8]) -> Result<T>
162where
163 T: de::Deserialize<'de>,
164{
165 let s = std::str::from_utf8(buf)?;
166 from_str(s)
167}
168
169pub fn from_body<T>(body: Body) -> Result<T>
210where
211 T: de::DeserializeOwned,
212{
213 T::deserialize(Deserializer { body })
214}
215
216impl<'de> de::Deserializer<'de> for Deserializer {
217 type Error = Error;
218
219 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
220 where
221 V: de::Visitor<'de>,
222 {
223 self.body.into_json_spec().deserialize_any(visitor)
224 }
225
226 fn deserialize_newtype_struct<V>(
227 self,
228 name: &'static str,
229 visitor: V,
230 ) -> Result<V::Value, Self::Error>
231 where
232 V: de::Visitor<'de>,
233 {
234 if name == "$hcl::Body" {
235 self.body.into_deserializer().deserialize_any(visitor)
237 } else {
238 self.body
240 .into_json_spec()
241 .deserialize_newtype_struct(name, visitor)
242 }
243 }
244
245 fn deserialize_enum<V>(
246 self,
247 name: &'static str,
248 variants: &'static [&'static str],
249 visitor: V,
250 ) -> Result<V::Value>
251 where
252 V: de::Visitor<'de>,
253 {
254 self.body
255 .into_json_spec()
256 .deserialize_enum(name, variants, visitor)
257 }
258
259 forward_to_deserialize_any! {
260 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
261 bytes byte_buf option unit unit_struct seq tuple
262 tuple_struct map struct identifier ignored_any
263 }
264}
265
266pub(crate) trait VariantName {
268 fn variant_name(&self) -> &'static str;
269}
270
271#[doc(hidden)]
273pub struct NewtypeStructDeserializer<T, E = Error> {
274 value: T,
275 marker: PhantomData<E>,
276}
277
278impl<T, E> NewtypeStructDeserializer<T, E> {
279 pub(crate) fn new(value: T) -> Self {
280 NewtypeStructDeserializer {
281 value,
282 marker: PhantomData,
283 }
284 }
285}
286
287impl<'de, T, E> de::Deserializer<'de> for NewtypeStructDeserializer<T, E>
288where
289 T: IntoDeserializer<'de, E>,
290 E: de::Error,
291{
292 type Error = E;
293
294 forward_to_deserialize_any! {
295 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
296 string bytes byte_buf option unit unit_struct newtype_struct seq
297 tuple tuple_struct map struct enum identifier ignored_any
298 }
299
300 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
301 where
302 V: de::Visitor<'de>,
303 {
304 visitor.visit_newtype_struct(self.value.into_deserializer())
305 }
306}
307
308pub(crate) struct OptionDeserializer<T, E = Error> {
309 value: Option<T>,
310 marker: PhantomData<E>,
311}
312
313impl<T, E> OptionDeserializer<T, E> {
314 pub(crate) fn new(value: Option<T>) -> Self {
315 OptionDeserializer {
316 value,
317 marker: PhantomData,
318 }
319 }
320}
321
322impl<'de, T, E> de::Deserializer<'de> for OptionDeserializer<T, E>
323where
324 T: IntoDeserializer<'de, E>,
325 E: de::Error,
326{
327 type Error = E;
328
329 forward_to_deserialize_any! {
330 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
331 string bytes byte_buf option unit unit_struct newtype_struct seq
332 tuple tuple_struct map struct enum identifier ignored_any
333 }
334
335 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
336 where
337 V: de::Visitor<'de>,
338 {
339 match self.value {
340 Some(value) => visitor.visit_some(value.into_deserializer()),
341 None => visitor.visit_none(),
342 }
343 }
344}
345
346pub(crate) struct EnumAccess<T, E = Error> {
347 value: T,
348 marker: PhantomData<E>,
349}
350
351impl<T, E> EnumAccess<T, E> {
352 pub(crate) fn new(value: T) -> Self {
353 EnumAccess {
354 value,
355 marker: PhantomData,
356 }
357 }
358}
359
360impl<'de, T, E> de::EnumAccess<'de> for EnumAccess<T, E>
361where
362 T: IntoDeserializer<'de, E> + VariantName,
363 E: de::Error,
364{
365 type Error = E;
366 type Variant = VariantAccess<T, E>;
367
368 fn variant_seed<S>(self, seed: S) -> Result<(S::Value, Self::Variant), Self::Error>
369 where
370 S: de::DeserializeSeed<'de>,
371 {
372 let variant_name = self.value.variant_name();
373
374 seed.deserialize(variant_name.into_deserializer())
375 .map(|variant| (variant, VariantAccess::new(self.value)))
376 }
377}
378
379#[doc(hidden)]
381pub struct VariantAccess<T, E = Error> {
382 value: T,
383 marker: PhantomData<E>,
384}
385
386impl<T, E> VariantAccess<T, E> {
387 fn new(value: T) -> Self {
388 VariantAccess {
389 value,
390 marker: PhantomData,
391 }
392 }
393}
394
395impl<'de, T, E> de::VariantAccess<'de> for VariantAccess<T, E>
396where
397 T: IntoDeserializer<'de, E>,
398 E: de::Error,
399{
400 type Error = E;
401
402 fn unit_variant(self) -> Result<(), Self::Error> {
403 de::Deserialize::deserialize(self.value.into_deserializer())
404 }
405
406 fn newtype_variant_seed<S>(self, seed: S) -> Result<S::Value, Self::Error>
407 where
408 S: de::DeserializeSeed<'de>,
409 {
410 seed.deserialize(self.value.into_deserializer())
411 }
412
413 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
414 where
415 V: de::Visitor<'de>,
416 {
417 self.value.into_deserializer().deserialize_seq(visitor)
418 }
419
420 fn struct_variant<V>(
421 self,
422 _fields: &'static [&'static str],
423 visitor: V,
424 ) -> Result<V::Value, Self::Error>
425 where
426 V: de::Visitor<'de>,
427 {
428 self.value.into_deserializer().deserialize_map(visitor)
429 }
430}
431
432pub(crate) struct FromStrVisitor<T> {
433 expecting: &'static str,
434 marker: PhantomData<T>,
435}
436
437impl<T> FromStrVisitor<T> {
438 pub(crate) fn new(expecting: &'static str) -> FromStrVisitor<T> {
439 FromStrVisitor {
440 expecting,
441 marker: PhantomData,
442 }
443 }
444}
445
446impl<T> de::Visitor<'_> for FromStrVisitor<T>
447where
448 T: std::str::FromStr,
449 T::Err: fmt::Display,
450{
451 type Value = T;
452
453 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
454 formatter.write_str(self.expecting)
455 }
456
457 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
458 where
459 E: de::Error,
460 {
461 T::from_str(value).map_err(de::Error::custom)
462 }
463}
464
465impl IntoDeserializer<'_, Error> for Identifier {
466 type Deserializer = StringDeserializer<Error>;
467
468 fn into_deserializer(self) -> Self::Deserializer {
469 self.into_inner().into_deserializer()
470 }
471}