serde_ply/de/
ply_file.rs

1use core::fmt;
2use serde::de::value::BytesDeserializer;
3use serde::de::{DeserializeSeed, MapAccess, SeqAccess, Visitor};
4use serde::{Deserialize, Deserializer};
5use std::io::{BufRead, Read};
6use std::marker::PhantomData;
7
8use crate::de::val_reader::{AsciiValReader, BinValReader, ScalarReader};
9use crate::de::RowDeserializer;
10use crate::{DeserializeError, ElementDef, PlyFormat, PlyHeader, PlyProperty};
11use byteorder::{BigEndian, LittleEndian};
12
13/// PLY file deserializer for element-by-element processing.
14///
15/// Use when you need to handle different element types separately
16/// or process large files incrementally. Unlike the simple [`crate::from_reader`] function,
17/// this gives you control over parsing each element type individually.
18///
19/// # Example
20/// ```rust
21/// use serde::Deserialize;
22/// use serde_ply::PlyReader;
23/// use std::io::{BufReader, Cursor};
24///
25/// #[derive(Deserialize)]
26/// struct Vertex { x: f32, y: f32, z: f32 }
27///
28/// #[derive(Deserialize)]
29/// struct Face { vertex_indices: Vec<u32> }
30///
31/// let ply_data = b"ply\nformat ascii 1.0\nelement vertex 1\nproperty float x\nproperty float y\nproperty float z\nelement face 1\nproperty list uchar uint vertex_indices\nend_header\n0.0 0.0 0.0\n3 0 1 2\n";
32/// let mut reader = PlyReader::from_reader(BufReader::new(Cursor::new(ply_data)))?;
33///
34/// let vertices: Vec<Vertex> = reader.next_element()?;
35/// let faces: Vec<Face> = reader.next_element()?;
36/// # Ok::<(), Box<dyn std::error::Error>>(())
37/// ```
38pub struct PlyReader<R> {
39    reader: R,
40    header: PlyHeader,
41    current_element: usize,
42}
43
44impl<R: BufRead> PlyReader<R> {
45    /// Create PLY deserializer from reader.
46    ///
47    /// Parses the PLY header immediately but doesn't read any element data.
48    /// Use [`Self::next_element`] to process elements sequentially.
49    pub fn from_reader(mut reader: R) -> Result<Self, DeserializeError> {
50        let header = PlyHeader::parse(&mut reader)?;
51        Ok(Self {
52            reader,
53            header,
54            current_element: 0,
55        })
56    }
57
58    /// Get the parsed PLY header.
59    pub fn header(&self) -> &PlyHeader {
60        &self.header
61    }
62
63    /// Get the current element definition.
64    ///
65    /// Returns the element that will be deserialized by the next call to
66    /// [`Self::next_element`]. Returns `None` if all elements have been processed.
67    /// Use this to inspect the element structure before deserializing.
68    pub fn current_element(&self) -> Option<&ElementDef> {
69        self.header.elem_defs.get(self.current_element)
70    }
71
72    /// Deserialize the next element.
73    ///
74    /// The type `T` should typically be a sequence of rows. for example `Vec<RowType>` where `RowType`
75    /// matches the properties of the current element. Use [`Self::current_element`] to
76    /// inspect the element definition beforehand.
77    ///
78    /// # Examples
79    ///
80    /// ```rust
81    /// use serde::Deserialize;
82    /// # use serde_ply::PlyReader;
83    /// # use std::io::{BufReader, Cursor};
84    ///
85    /// #[derive(Deserialize)]
86    /// struct Vertex { x: f32, y: f32, z: f32 }
87    ///
88    /// # let ply_data = "ply\nformat ascii 1.0\nelement vertex 1\nproperty float x\nproperty float y\nproperty float z\nend_header\n1.0 2.0 3.0\n";
89    /// # let cursor = Cursor::new(ply_data);
90    /// # let mut deserializer = PlyReader::from_reader(BufReader::new(cursor))?;
91    /// let vertices: Vec<Vertex> = deserializer.next_element()?;
92    /// assert_eq!(vertices.len(), 1);
93    /// # Ok::<(), Box<dyn std::error::Error>>(())
94    /// ```
95    pub fn next_element<'a, T>(&mut self) -> Result<T, DeserializeError>
96    where
97        T: Deserialize<'a>,
98    {
99        // Deserialize exactly a single value from a map deserializer.
100        struct FirstValueVisitor<T>(PhantomData<T>);
101        impl<'de, T> Visitor<'de> for FirstValueVisitor<T>
102        where
103            T: Deserialize<'de>,
104        {
105            type Value = T;
106
107            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
108                formatter.write_str("a map with at least one entry")
109            }
110
111            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
112            where
113                A: MapAccess<'de>,
114            {
115                // Use next value directly. This is NOT ok in general as next_key might
116                // increment things instead but it's fine we're in charge.
117                map.next_value::<T>()
118            }
119        }
120        self.deserialize_map(FirstValueVisitor(PhantomData))
121    }
122}
123
124impl<'de, R: BufRead> Deserializer<'de> for &mut PlyReader<R> {
125    type Error = DeserializeError;
126
127    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
128    where
129        V: Visitor<'de>,
130    {
131        self.deserialize_map(visitor)
132    }
133
134    fn deserialize_struct<V>(
135        self,
136        _name: &'static str,
137        _fields: &'static [&'static str],
138        visitor: V,
139    ) -> Result<V::Value, Self::Error>
140    where
141        V: Visitor<'de>,
142    {
143        self.deserialize_map(visitor)
144    }
145
146    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
147    where
148        V: Visitor<'de>,
149    {
150        visitor.visit_map(self)
151    }
152
153    fn deserialize_newtype_struct<V>(
154        self,
155        _name: &'static str,
156        visitor: V,
157    ) -> Result<V::Value, Self::Error>
158    where
159        V: Visitor<'de>,
160    {
161        visitor.visit_newtype_struct(self)
162    }
163
164    serde::forward_to_deserialize_any! {
165        bool i8 u8 i16 u16 i32 u32 i64 u64 f32 f64 char str string
166        bytes byte_buf option unit unit_struct tuple
167        tuple_struct enum identifier ignored_any seq
168    }
169}
170
171impl<'de, R: Read> MapAccess<'de> for &mut PlyReader<R> {
172    type Error = DeserializeError;
173
174    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
175    where
176        K: DeserializeSeed<'de>,
177    {
178        if self.current_element >= self.header.elem_defs.len() {
179            return Ok(None);
180        }
181        let element_name = &self.header.elem_defs[self.current_element].name.as_bytes();
182        seed.deserialize(BytesDeserializer::new(element_name))
183            .map(Some)
184    }
185
186    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
187    where
188        V: DeserializeSeed<'de>,
189    {
190        let elem_def = &self.header.elem_defs[self.current_element];
191        self.current_element += 1;
192
193        match self.header.format {
194            PlyFormat::Ascii => seed.deserialize(ElementSeqDeserializer::<_, AsciiValReader>::new(
195                &elem_def.properties,
196                &mut self.reader,
197                elem_def.count,
198            )),
199            PlyFormat::BinaryLittleEndian => seed.deserialize(ElementSeqDeserializer::<
200                _,
201                BinValReader<LittleEndian>,
202            >::new(
203                &elem_def.properties,
204                &mut self.reader,
205                elem_def.count,
206            )),
207            PlyFormat::BinaryBigEndian => {
208                seed.deserialize(ElementSeqDeserializer::<_, BinValReader<BigEndian>>::new(
209                    &elem_def.properties,
210                    &mut self.reader,
211                    elem_def.count,
212                ))
213            }
214        }
215    }
216}
217
218pub(crate) struct ElementSeqDeserializer<'a, R: Read, S: ScalarReader> {
219    row: RowDeserializer<'a, R, S>,
220    remaining: usize,
221}
222
223impl<'a, R: Read, S: ScalarReader> ElementSeqDeserializer<'a, R, S> {
224    pub(crate) fn new(properties: &'a [PlyProperty], reader: &'a mut R, row_count: usize) -> Self {
225        Self {
226            row: RowDeserializer::new(reader, properties),
227            remaining: row_count,
228        }
229    }
230}
231
232impl<'de, R: Read, S: ScalarReader> Deserializer<'de> for ElementSeqDeserializer<'_, R, S> {
233    type Error = DeserializeError;
234
235    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
236    where
237        V: Visitor<'de>,
238    {
239        self.deserialize_seq(visitor)
240    }
241
242    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
243    where
244        V: Visitor<'de>,
245    {
246        visitor.visit_seq(self)
247    }
248
249    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
250    where
251        V: Visitor<'de>,
252    {
253        visitor.visit_some(self)
254    }
255
256    fn deserialize_newtype_struct<V>(
257        self,
258        _name: &'static str,
259        visitor: V,
260    ) -> Result<V::Value, Self::Error>
261    where
262        V: Visitor<'de>,
263    {
264        visitor.visit_newtype_struct(self)
265    }
266
267    serde::forward_to_deserialize_any! {
268        bool i8 u8 i16 u16 i32 u32 f32 f64 char str string
269        bytes byte_buf unit unit_struct map struct tuple
270        tuple_struct enum identifier ignored_any i64 u64
271    }
272}
273
274impl<'de, R: Read, S: ScalarReader> SeqAccess<'de> for ElementSeqDeserializer<'_, R, S> {
275    type Error = DeserializeError;
276
277    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
278    where
279        T: DeserializeSeed<'de>,
280    {
281        if self.remaining == 0 {
282            return Ok(None);
283        }
284        self.remaining -= 1;
285        seed.deserialize(&mut self.row).map(Some)
286    }
287
288    fn size_hint(&self) -> Option<usize> {
289        Some(self.remaining)
290    }
291}