1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use crate::{ reader::{helpers::ReadHelpers, VertexReader}, Config, DefaultConfig, Result, Settings, }; use byteorder::{ReadBytesExt, LE}; use std::io::Read; use std::marker::PhantomData; pub struct SurfaceReader<R> { pub settings: Settings, pub count: i32, pub remaining: i32, pub(crate) read: R, pub(crate) poison: bool, } impl<R: Read> SurfaceReader<R> { pub fn new(mut v: VertexReader<R>) -> Result<SurfaceReader<R>> { assert!(!v.poison); while v.remaining > 0 { v.next::<DefaultConfig>()?; } let count = v.read.read_i32::<LE>()?; Ok(SurfaceReader { settings: v.settings, count, remaining: count, read: v.read, poison: false, }) } pub fn next<C: Config>(&mut self) -> Result<Option<[C::VertexIndex; 3]>> { assert!(!self.poison); let result = self.next_impl::<C>(); if result.is_err() { self.poison = true; } result } fn next_impl<C: Config>(&mut self) -> Result<Option<[C::VertexIndex; 3]>> { if self.remaining <= 0 { return Ok(None); } self.remaining -= 3; Ok(Some([ self .read .read_vertex_index(self.settings.vertex_index_size)?, self .read .read_vertex_index(self.settings.vertex_index_size)?, self .read .read_vertex_index(self.settings.vertex_index_size)?, ])) } pub fn iter<I>(&mut self) -> SurfaceIterator<R, I> { SurfaceIterator { reader: self, phantom: PhantomData, } } } pub struct SurfaceIterator<'a, R, C = DefaultConfig> { reader: &'a mut SurfaceReader<R>, phantom: PhantomData<C>, } impl<R: Read, C: Config> Iterator for SurfaceIterator<'_, R, C> { type Item = Result<[C::VertexIndex; 3]>; fn next(&mut self) -> Option<Self::Item> { self .reader .next::<C>() .map_or_else(|e| Some(Err(e)), |v| v.map(Ok)) } fn size_hint(&self) -> (usize, Option<usize>) { ( self.reader.remaining as usize, Some(self.reader.remaining as usize), ) } } impl<R: Read, C: Config> ExactSizeIterator for SurfaceIterator<'_, R, C> { fn len(&self) -> usize { self.reader.remaining as usize } }