use json;
use root;
use std::{fmt, io, iter, ops, slice};
use accessor::Accessor;
use animation::Animation;
use buffer::{Buffer, View};
use camera::Camera;
use image::Image;
use material::Material;
use mesh::Mesh;
use scene::{Node, Scene};
use skin::Skin;
use texture::{Sampler, Texture};
use Error;
pub struct Gltf {
root: root::Root,
}
pub struct Unvalidated(Gltf);
#[derive(Clone, Debug)]
pub struct Accessors<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::accessor::Accessor>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Animations<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::animation::Animation>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Buffers<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::buffer::Buffer>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Views<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::buffer::View>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Cameras<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::camera::Camera>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Images<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::image::Image>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Materials<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::material::Material>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Meshes<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::mesh::Mesh>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Nodes<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::scene::Node>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Samplers<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::texture::Sampler>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Scenes<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::scene::Scene>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Skins<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::skin::Skin>>,
gltf: &'a Gltf,
}
#[derive(Clone, Debug)]
pub struct Textures<'a> {
iter: iter::Enumerate<slice::Iter<'a, json::texture::Texture>>,
gltf: &'a Gltf,
}
impl Unvalidated {
pub fn as_json(&self) -> &json::Root {
self.0.root.as_json()
}
pub unsafe fn skip_validation(self) -> Gltf {
self.0
}
pub fn validate_minimally(self) -> Result<Gltf, Error> {
use json::validation::Validate;
let mut errs = vec![];
{
let json = self.as_json();
json.validate_minimally(
json,
|| json::Path::new(),
&mut |path, err| errs.push((path(), err)),
);
}
if errs.is_empty() {
Ok(self.0)
} else {
Err(Error::Validation(errs))
}
}
pub fn validate_completely(self) -> Result<Gltf, Error> {
use json::validation::Validate;
let mut errs = vec![];
{
let json = self.as_json();
json.validate_minimally(
json,
|| json::Path::new(),
&mut |path, err| errs.push((path(), err)),
);
json.validate_completely(
json,
|| json::Path::new(),
&mut |path, err| errs.push((path(), err)),
);
}
if errs.is_empty() {
Ok(self.0)
} else {
Err(Error::Validation(errs))
}
}
}
impl Gltf {
fn from_json(json: json::Root) -> Self {
Gltf {
root: root::Root::new(json),
}
}
pub fn from_reader<R>(reader: R) -> Result<Unvalidated, Error>
where R: io::Read
{
let json: json::Root = json::from_reader(reader)?;
Ok(Unvalidated(Gltf::from_json(json)))
}
pub fn from_slice(slice: &[u8]) -> Result<Unvalidated, Error> {
let json: json::Root = json::from_slice(slice)?;
Ok(Unvalidated(Gltf::from_json(json)))
}
pub fn from_str(slice: &str) -> Result<Unvalidated, Error> {
let json: json::Root = json::from_str(slice)?;
Ok(Unvalidated(Gltf::from_json(json)))
}
pub fn from_value(value: json::Value) -> Result<Unvalidated, Error> {
let json: json::Root = json::from_value(value)?;
Ok(Unvalidated(Gltf::from_json(json)))
}
pub fn accessors(&self) -> Accessors {
Accessors {
iter: self.as_json().accessors.iter().enumerate(),
gltf: self,
}
}
pub fn animations(&self) -> Animations {
Animations {
iter: self.as_json().animations.iter().enumerate(),
gltf: self,
}
}
pub fn buffers(&self) -> Buffers {
Buffers {
iter: self.as_json().buffers.iter().enumerate(),
gltf: self,
}
}
pub fn views(&self) -> Views {
Views {
iter: self.as_json().buffer_views.iter().enumerate(),
gltf: self,
}
}
pub fn cameras(&self) -> Cameras {
Cameras {
iter: self.as_json().cameras.iter().enumerate(),
gltf: self,
}
}
pub fn images(&self) -> Images {
Images {
iter: self.as_json().images.iter().enumerate(),
gltf: self,
}
}
pub fn materials(&self) -> Materials {
Materials {
iter: self.as_json().materials.iter().enumerate(),
gltf: self,
}
}
pub fn meshes(&self) -> Meshes {
Meshes {
iter: self.as_json().meshes.iter().enumerate(),
gltf: self,
}
}
pub fn nodes(&self) -> Nodes {
Nodes {
iter: self.as_json().nodes.iter().enumerate(),
gltf: self,
}
}
pub fn samplers(&self) -> Samplers {
Samplers {
iter: self.as_json().samplers.iter().enumerate(),
gltf: self,
}
}
pub fn scenes(&self) -> Scenes {
Scenes {
iter: self.as_json().scenes.iter().enumerate(),
gltf: self,
}
}
pub fn skins(&self) -> Skins {
Skins {
iter: self.as_json().skins.iter().enumerate(),
gltf: self,
}
}
pub fn textures(&self) -> Textures {
Textures {
iter: self.as_json().textures.iter().enumerate(),
gltf: self,
}
}
}
impl<'a> fmt::Debug for Gltf {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.root)
}
}
impl<'a> ops::Deref for Gltf {
type Target = root::Root;
fn deref(&self) -> &Self::Target {
&self.root
}
}
impl<'a> ExactSizeIterator for Accessors<'a> {}
impl<'a> Iterator for Accessors<'a> {
type Item = Accessor<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Accessor::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Animations<'a> {}
impl<'a> Iterator for Animations<'a> {
type Item = Animation<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Animation::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Buffers<'a> {}
impl<'a> Iterator for Buffers<'a> {
type Item = Buffer<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Buffer::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Views<'a> {}
impl<'a> Iterator for Views<'a> {
type Item = View<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| View::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Cameras<'a> {}
impl<'a> Iterator for Cameras<'a> {
type Item = Camera<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Camera::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Images<'a> {}
impl<'a> Iterator for Images<'a> {
type Item = Image<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|(index, json)| Image::new(self.gltf, index, json))
}
}
impl<'a> ExactSizeIterator for Materials<'a> {}
impl<'a> Iterator for Materials<'a> {
type Item = Material<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Material::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Meshes<'a> {}
impl<'a> Iterator for Meshes<'a> {
type Item = Mesh<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Mesh::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Nodes<'a> {}
impl<'a> Iterator for Nodes<'a> {
type Item = Node<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Node::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Samplers<'a> {}
impl<'a> Iterator for Samplers<'a> {
type Item = Sampler<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Sampler::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Scenes<'a> {}
impl<'a> Iterator for Scenes<'a> {
type Item = Scene<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Scene::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Skins<'a> {}
impl<'a> Iterator for Skins<'a> {
type Item = Skin<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Skin::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a> ExactSizeIterator for Textures<'a> {}
impl<'a> Iterator for Textures<'a> {
type Item = Texture<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(index, json)| Texture::new(self.gltf, index, json))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}