scuffle_amf0/de/
stream.rs

1use std::fmt;
2
3use scuffle_bytes_util::zero_copy::ZeroCopyReader;
4use serde::de::SeqAccess;
5
6use crate::Amf0Error;
7use crate::decoder::Amf0Decoder;
8
9/// Deserializer stream for AMF0 values.
10///
11/// This is a stream of AMF0 values that can be deserialized into a type.
12///
13/// It is created by calling [`Amf0Decoder::deserialize_stream`].
14#[must_use = "Iterators are lazy and do nothing unless consumed"]
15pub struct Amf0DeserializerStream<'a, R, T> {
16    de: &'a mut Amf0Decoder<R>,
17    _marker: std::marker::PhantomData<T>,
18}
19
20impl<'a, R, T> Amf0DeserializerStream<'a, R, T> {
21    pub(crate) fn new(de: &'a mut Amf0Decoder<R>) -> Self {
22        Self {
23            de,
24            _marker: std::marker::PhantomData,
25        }
26    }
27}
28
29impl<'de, R, T> Iterator for Amf0DeserializerStream<'_, R, T>
30where
31    R: ZeroCopyReader<'de>,
32    T: serde::de::Deserialize<'de>,
33{
34    type Item = Result<T, Amf0Error>;
35
36    fn next(&mut self) -> Option<Self::Item> {
37        match self.de.has_remaining() {
38            Ok(true) => Some(T::deserialize(&mut *self.de)),
39            Ok(false) => None,
40            Err(err) => Some(Err(err)),
41        }
42    }
43}
44
45impl<'de, R, T> std::iter::FusedIterator for Amf0DeserializerStream<'_, R, T>
46where
47    R: ZeroCopyReader<'de>,
48    T: serde::de::Deserialize<'de>,
49{
50}
51
52pub(crate) struct MultiValueDe<'a, R> {
53    pub(crate) de: &'a mut Amf0Decoder<R>,
54}
55
56impl<'de, R> SeqAccess<'de> for MultiValueDe<'_, R>
57where
58    R: ZeroCopyReader<'de>,
59{
60    type Error = Amf0Error;
61
62    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
63    where
64        T: serde::de::DeserializeSeed<'de>,
65    {
66        if self.de.has_remaining()? {
67            seed.deserialize(&mut *self.de).map(Some)
68        } else {
69            Ok(None)
70        }
71    }
72}
73
74pub(crate) const MULTI_VALUE_NEW_TYPE: &str = "___AMF0_MULTI_VALUE__DO_NOT_USE__";
75
76/// A wrapper around a value that can be deserialized as a series of individual values.
77///
78/// This is useful if your amf0 encoded data is a series of individual values.
79pub struct MultiValue<T>(pub T);
80
81impl<'de, T> serde::de::Deserialize<'de> for MultiValue<T>
82where
83    T: serde::de::Deserialize<'de>,
84{
85    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
86    where
87        D: serde::Deserializer<'de>,
88    {
89        struct Visitor<T>(std::marker::PhantomData<T>);
90
91        impl<'de, T> serde::de::Visitor<'de> for Visitor<T>
92        where
93            T: serde::de::Deserialize<'de>,
94        {
95            type Value = T;
96
97            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
98                formatter.write_str("a series of values")
99            }
100
101            fn visit_seq<V>(self, seq: V) -> Result<Self::Value, V::Error>
102            where
103                V: serde::de::SeqAccess<'de>,
104            {
105                T::deserialize(serde::de::value::SeqAccessDeserializer::new(seq))
106            }
107        }
108
109        deserializer
110            .deserialize_newtype_struct(MULTI_VALUE_NEW_TYPE, Visitor(std::marker::PhantomData))
111            .map(MultiValue)
112    }
113}