1use std::path::Path;
2use std::{fs, io, ops};
3
4use crate::binary;
5use crate::document::Document;
6use crate::error::Result;
7
8#[derive(Clone, Debug)]
10pub struct Gltf {
11 pub document: Document,
13
14 pub blob: Option<Vec<u8>>,
16}
17
18impl Gltf {
19 pub fn open<P>(path: P) -> Result<Self>
21 where
22 P: AsRef<Path>,
23 {
24 let file = fs::File::open(path)?;
25 let reader = io::BufReader::new(file);
26 let gltf = Self::from_reader(reader)?;
27 Ok(gltf)
28 }
29 pub fn from_reader_without_validation<R>(mut reader: R) -> Result<Self>
31 where
32 R: io::Read + io::Seek,
33 {
34 let mut magic = [0u8; 4];
35 reader.read_exact(&mut magic)?;
36 reader.seek(io::SeekFrom::Current(-4))?;
37 let (json, blob): (json::Root, Option<Vec<u8>>);
38 if magic.starts_with(b"glTF") {
39 let mut glb = binary::Glb::from_reader(reader)?;
40 json = json::deserialize::from_slice(&glb.content)?;
42 blob = glb.body.take().map(|x| x.into_owned());
43 } else {
44 json = json::deserialize::from_reader(reader)?;
45 blob = None;
46 };
47 let document = Document::from_json_without_validation(json);
48 Ok(Gltf { document, blob })
49 }
50 pub fn from_reader<R>(reader: R) -> Result<Self>
52 where
53 R: io::Read + io::Seek,
54 {
55 let gltf = Self::from_reader_without_validation(reader)?;
56 gltf.document.validate()?;
57 Ok(gltf)
58 }
59
60 pub fn from_slice_without_validation(slice: &[u8]) -> Result<Self> {
61 let (json, blob): (json::Root, Option<Vec<u8>>);
62 if slice.starts_with(b"glTF") {
63 let mut glb = binary::Glb::from_slice(slice)?;
64 json = json::deserialize::from_slice(&glb.content)?;
65 blob = glb.body.take().map(|x| x.into_owned());
66 } else {
67 json = json::deserialize::from_slice(slice)?;
68 blob = None;
69 };
70 let document = Document::from_json_without_validation(json);
71 Ok(Gltf { document, blob })
72 }
73
74 pub fn from_slice(slice: &[u8]) -> Result<Self> {
75 let gltf = Self::from_slice_without_validation(slice)?;
76 gltf.document.validate()?;
77 Ok(gltf)
78 }
79}
80
81impl ops::Deref for Gltf {
82 type Target = Document;
83 fn deref(&self) -> &Self::Target {
84 &self.document
85 }
86}
87
88impl ops::DerefMut for Gltf {
89 fn deref_mut(&mut self) -> &mut Self::Target {
90 &mut self.document
91 }
92}