tokio_dbus/body/
load_array.rs

1use std::marker::PhantomData;
2
3use crate::buf::MAX_ARRAY_LENGTH;
4use crate::error::ErrorKind;
5use crate::{ty, Body};
6use crate::{Error, Frame, Read, Result};
7
8/// Read an array from a buffer.
9///
10/// See [`Body::load_array`].
11///
12/// [`Body::load_array`]: crate::Body::load_array
13pub struct LoadArray<'de, T> {
14    buf: Body<'de>,
15    _marker: PhantomData<T>,
16}
17
18impl<'de, T> LoadArray<'de, T> {
19    #[inline]
20    pub(crate) fn from_mut(buf: &mut Body<'de>) -> Result<LoadArray<'de, T>> {
21        let bytes = buf.load::<u32>()?;
22
23        if bytes > MAX_ARRAY_LENGTH {
24            return Err(Error::new(ErrorKind::ArrayTooLong(bytes)));
25        }
26
27        let buf = buf.read_until(bytes as usize);
28        Ok(LoadArray::new(buf))
29    }
30
31    /// Construct a new array reader around a buffer.
32    pub(crate) fn new(buf: Body<'de>) -> Self {
33        LoadArray {
34            buf,
35            _marker: PhantomData,
36        }
37    }
38}
39
40impl<'de, T> LoadArray<'de, T>
41where
42    T: Frame,
43{
44    /// Load the next value from the array.
45    ///
46    /// See [`Body::load_array`].
47    ///
48    /// [`Body::load_array`]: crate::Body::load_array
49    pub fn load(&mut self) -> Result<Option<T>> {
50        if self.buf.is_empty() {
51            return Ok(None);
52        }
53
54        Ok(Some(self.buf.load()?))
55    }
56}
57
58impl<'de, T> LoadArray<'de, T>
59where
60    T: ty::Unsized,
61    T::Target: Read,
62{
63    /// Read the next value from the array.
64    ///
65    /// See [`Body::load_array`].
66    ///
67    /// [`Body::load_array`]: crate::Body::load_array
68    pub fn read(&mut self) -> Result<Option<&'de T::Target>> {
69        if self.buf.is_empty() {
70            return Ok(None);
71        }
72
73        Ok(Some(T::Target::read_from(&mut self.buf)?))
74    }
75}
76
77impl<'de, T> LoadArray<'de, ty::Array<T>>
78where
79    T: ty::Marker,
80{
81    /// Read an array from within the array.
82    ///
83    /// See [`Body::load_struct`].
84    pub fn load_array(&mut self) -> Result<Option<LoadArray<'de, T>>> {
85        if self.buf.is_empty() {
86            return Ok(None);
87        }
88
89        Ok(Some(LoadArray::from_mut(&mut self.buf)?))
90    }
91}
92
93impl<'de, T> LoadArray<'de, T>
94where
95    T: ty::Fields,
96{
97    /// Read a struct from within the array.
98    ///
99    /// See [`Body::load_struct`].
100    pub fn load_struct(&mut self) -> Result<Option<T::Return<'de>>> {
101        if self.buf.is_empty() {
102            return Ok(None);
103        }
104
105        Ok(Some(T::load_struct(&mut self.buf)?))
106    }
107}