gltf_v1/
buffer.rs

1use std::ops;
2
3use json::buffer::{BufferType, BufferViewType};
4
5use crate::document::Document;
6
7/// A buffer points to binary data representing geometry, animations, or skins.
8#[derive(Clone, Debug)]
9pub struct Buffer<'a> {
10    /// The parent `Document` struct.
11    #[allow(dead_code)]
12    document: &'a Document,
13
14    /// The corresponding JSON index.
15    index: &'a String,
16
17    /// The corresponding JSON struct.
18    json: &'a json::Buffer,
19}
20
21/// A view into a buffer generally representing a subset of the buffer.
22#[derive(Clone, Debug)]
23pub struct View<'a> {
24    /// The parent `Document` struct.
25    #[allow(dead_code)]
26    document: &'a Document,
27
28    /// The corresponding JSON index.
29    index: &'a String,
30
31    /// The corresponding JSON struct.
32    json: &'a json::BufferView,
33
34    parent: Buffer<'a>,
35}
36
37/// Describes a buffer data source.
38#[derive(Clone, Debug)]
39pub enum Source<'a> {
40    /// Buffer data is contained in the `BIN` section of binary glTF.
41    Bin,
42
43    /// Buffer data is contained in an external data source.
44    Uri(&'a str),
45}
46
47#[derive(Clone, Debug)]
48pub struct Data(pub Vec<u8>);
49
50impl ops::Deref for Data {
51    type Target = [u8];
52    fn deref(&self) -> &Self::Target {
53        self.0.as_slice()
54    }
55}
56
57impl<'a> Buffer<'a> {
58    /// Constructs a `Buffer`.
59    pub(crate) fn new(document: &'a Document, index: &'a String, json: &'a json::Buffer) -> Self {
60        Self {
61            document,
62            index,
63            json,
64        }
65    }
66
67    /// Returns the internal JSON index.
68    pub fn index(&self) -> &str {
69        self.index
70    }
71
72    pub fn source(&self) -> Source<'a> {
73        if self.index == "binary_glTF" {
74            Source::Bin
75        } else {
76            Source::Uri(&self.json.uri)
77        }
78    }
79
80    pub fn length(&self) -> usize {
81        self.json.byte_length.0 as usize
82    }
83
84    pub fn name(&self) -> Option<&'a str> {
85        self.json.name.as_deref()
86    }
87
88    pub fn target(&self) -> Option<BufferType> {
89        self.json.type_.map(|x| x.unwrap())
90    }
91}
92
93impl<'a> View<'a> {
94    /// Constructs a `View`.
95    pub(crate) fn new(
96        document: &'a Document,
97        index: &'a String,
98        json: &'a json::BufferView,
99    ) -> Self {
100        let parent = document
101            .buffers()
102            .find(|x| x.index == json.buffer.value())
103            .unwrap();
104        Self {
105            document,
106            index,
107            json,
108            parent,
109        }
110    }
111
112    /// Returns the internal JSON index.
113    pub fn index(&self) -> &str {
114        self.index
115    }
116
117    pub fn buffer(&self) -> &Buffer<'a> {
118        &self.parent
119    }
120
121    pub fn length(&self) -> usize {
122        self.json.byte_length.0 as usize
123    }
124    pub fn offset(&self) -> usize {
125        self.json.byte_offset.0 as usize
126    }
127    pub fn name(&self) -> Option<&'a str> {
128        self.json.name.as_deref()
129    }
130
131    pub fn target(&self) -> Option<BufferViewType> {
132        self.json.target.map(|target| target.unwrap())
133    }
134}
135
136/// An `Iterator` that visits every buffer in a glTF asset.
137#[derive(Clone, Debug)]
138pub struct Buffers<'a> {
139    /// Internal buffer iterator.
140    pub(crate) iter: indexmap::map::Iter<'a, String, gltf_v1_json::Buffer>,
141
142    /// The internal root glTF object.
143    pub(crate) document: &'a Document,
144}
145
146impl ExactSizeIterator for Buffers<'_> {}
147impl<'a> Iterator for Buffers<'a> {
148    type Item = Buffer<'a>;
149    fn next(&mut self) -> Option<Self::Item> {
150        self.iter
151            .next()
152            .map(|(index, json)| Buffer::new(self.document, index, json))
153    }
154    fn size_hint(&self) -> (usize, Option<usize>) {
155        self.iter.size_hint()
156    }
157    fn count(self) -> usize {
158        self.iter.count()
159    }
160    fn last(self) -> Option<Self::Item> {
161        let document = self.document;
162        self.iter
163            .last()
164            .map(|(index, json)| Buffer::new(document, index, json))
165    }
166    fn nth(&mut self, n: usize) -> Option<Self::Item> {
167        self.iter
168            .nth(n)
169            .map(|(index, json)| Buffer::new(self.document, index, json))
170    }
171}
172
173/// An `Iterator` that visits every buffer view in a glTF asset.
174#[derive(Clone, Debug)]
175pub struct Views<'a> {
176    /// Internal buffer view iterator.
177    pub(crate) iter: indexmap::map::Iter<'a, String, gltf_v1_json::BufferView>,
178
179    /// The internal root glTF object.
180    pub(crate) document: &'a Document,
181}
182
183impl ExactSizeIterator for Views<'_> {}
184impl<'a> Iterator for Views<'a> {
185    type Item = View<'a>;
186    fn next(&mut self) -> Option<Self::Item> {
187        self.iter
188            .next()
189            .map(|(index, json)| View::new(self.document, index, json))
190    }
191    fn size_hint(&self) -> (usize, Option<usize>) {
192        self.iter.size_hint()
193    }
194    fn count(self) -> usize {
195        self.iter.count()
196    }
197    fn last(self) -> Option<Self::Item> {
198        let document = self.document;
199        self.iter
200            .last()
201            .map(|(index, json)| View::new(document, index, json))
202    }
203    fn nth(&mut self, n: usize) -> Option<Self::Item> {
204        self.iter
205            .nth(n)
206            .map(|(index, json)| View::new(self.document, index, json))
207    }
208}