From e9728ce51bafa7c1016e38125681de2d508da998 Mon Sep 17 00:00:00 2001 From: Hyeon Kim Date: Sat, 21 Mar 2020 15:46:06 +0900 Subject: [PATCH] Run rustfmt --- benches/bench.rs | 20 +-- examples/glium.rs | 42 ++++--- src/error.rs | 34 +++--- src/lib.rs | 145 ++++++++++++++++------ src/raw/lexer.rs | 27 +++-- src/raw/material.rs | 80 ++++++------ src/raw/mod.rs | 4 +- src/raw/object.rs | 274 +++++++++++++++++++++++------------------- tests/obj.rs | 76 ++++++++++-- tests/raw-basics.rs | 28 +++-- tests/raw-group.rs | 29 +++-- tests/raw-material.rs | 81 ++++++++----- 12 files changed, 524 insertions(+), 316 deletions(-) diff --git a/benches/bench.rs b/benches/bench.rs index 9051651..fea17a1 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -16,20 +16,28 @@ use test::Bencher; use obj::raw::parse_obj; fn load_file(filename: &str) -> Vec { - use std::path::Path; use std::fs::File; use std::io::Read; + use std::path::Path; let path = Path::new("tests").join("fixtures").join(filename); let mut file = match File::open(&path) { Ok(f) => f, - Err(e) => panic!("Failed to open \"{}\". \x1b[31m{}\x1b[0m", path.to_string_lossy(), e) + Err(e) => panic!( + "Failed to open \"{}\". \x1b[31m{}\x1b[0m", + path.to_string_lossy(), + e + ), }; let mut data = Vec::new(); match file.read_to_end(&mut data) { - Err(e) => panic!("Failed to read \"{}\". \x1b[31m{}\x1b[0m", path.to_string_lossy(), e), - Ok(_) => () + Err(e) => panic!( + "Failed to read \"{}\". \x1b[31m{}\x1b[0m", + path.to_string_lossy(), + e + ), + Ok(_) => (), } data @@ -39,7 +47,5 @@ fn load_file(filename: &str) -> Vec { fn sponza(b: &mut Bencher) { let data = load_file("sponza.obj"); let mut data = std::io::Cursor::new(&data[..]); - b.iter(|| { - parse_obj(&mut data).unwrap() - }); + b.iter(|| parse_obj(&mut data).unwrap()); } diff --git a/examples/glium.rs b/examples/glium.rs index fcb0f55..3e21237 100644 --- a/examples/glium.rs +++ b/examples/glium.rs @@ -13,22 +13,23 @@ //! //! cargo run --example glium --features glium-support -#[macro_use] extern crate glium; +#[macro_use] +extern crate glium; extern crate obj; #[cfg(feature = "glium-support")] fn main() { + use glium::glutin::dpi::LogicalSize; + use glium::{glutin, Program}; + use obj::*; + use std::default::Default; use std::fs::File; use std::io::BufReader; - use std::default::Default; - use obj::*; - use glium::{Program, glutin}; - use glium::glutin::dpi::LogicalSize; let mut events_loop = glutin::EventsLoop::new(); // building the display, ie. the main object - + let window = glutin::WindowBuilder::new() .with_dimensions(LogicalSize::new(500.0, 400.0)) .with_title("obj-rs"); @@ -43,7 +44,9 @@ fn main() { let vb = obj.vertex_buffer(&display).unwrap(); let ib = obj.index_buffer(&display).unwrap(); - let program = Program::from_source(&display, r#" + let program = Program::from_source( + &display, + r#" #version 410 uniform mat4 matrix; @@ -57,7 +60,8 @@ fn main() { gl_Position = matrix * vec4(position, 1.0); _normal = normalize(normal); } - "#, r#" + "#, + r#" #version 410 uniform vec3 light; @@ -68,7 +72,10 @@ fn main() { void main() { result = vec4(clamp(dot(_normal, -light), 0.0f, 1.0f) * vec3(1.0f, 0.93f, 0.56f), 1.0f); } - "#, None).unwrap(); + "#, + None, + ) + .unwrap(); // drawing a frame let uniforms = uniform! { @@ -107,19 +114,22 @@ fn main() { sleep(Duration::from_millis(17)); // polling and handling the events received by the window - events_loop.poll_events(|event| { - match event { - glutin::Event::WindowEvent {event: glutin::WindowEvent::CloseRequested, ..} => running = false, - _ => () - } + events_loop.poll_events(|event| match event { + glutin::Event::WindowEvent { + event: glutin::WindowEvent::CloseRequested, + .. + } => running = false, + _ => (), }); } } #[cfg(not(feature = "glium-support"))] fn main() { - println!("\n\ + println!( + "\n\ Please execute it with \x1b[4m--features glium-support\x1b[24m the option - $ \x1b[33mcargo run --example glium --features glium-support\x1b[0m\n"); + $ \x1b[33mcargo run --example glium --features glium-support\x1b[0m\n" + ); } diff --git a/src/error.rs b/src/error.rs index 7116c8b..e9c78a3 100644 --- a/src/error.rs +++ b/src/error.rs @@ -8,11 +8,11 @@ //! Contains helper structs for error handling -use std::fmt; -use std::io; -use std::num::{ParseIntError, ParseFloatError}; use std::convert::From; use std::error::Error; +use std::fmt; +use std::io; +use std::num::{ParseFloatError, ParseIntError}; /// A type for results generated by `load_obj` and `load_mtl` where the `Err` type is hard-wired to /// `ObjError` @@ -31,17 +31,17 @@ pub enum ObjError { /// Tried to parse floating point number frome the `obj` file, but failed. ParseFloat(ParseFloatError), /// `LoadError` has been occurred during parseing the `obj` file. - Load(LoadError) + Load(LoadError), } macro_rules! implmnt { - ($name:ident, $error:path) => ( + ($name:ident, $error:path) => { impl From<$error> for ObjError { fn from(err: $error) -> Self { ObjError::$name(err) } } - ) + }; } impl fmt::Display for ObjError { @@ -105,7 +105,10 @@ pub enum LoadErrorKind { impl LoadError { /// Creates a new custom error from a specified kind/description. pub fn new(kind: LoadErrorKind, desc: &'static str) -> Self { - LoadError { kind: kind, desc: desc } + LoadError { + kind: kind, + desc: desc, + } } } @@ -115,7 +118,9 @@ impl Error for LoadError { LoadErrorKind::UnexpectedStatement => "Met unexpected statement", LoadErrorKind::WrongNumberOfArguments => "Received wrong number of arguments", LoadErrorKind::WrongTypeOfArguments => "Received unexpected type of arguments", - LoadErrorKind::UntriangulatedModel => "Model should be triangulated first to be loaded properly", + LoadErrorKind::UntriangulatedModel => { + "Model should be triangulated first to be loaded properly" + } LoadErrorKind::InsufficientData => "Model cannot be transformed into requested form", } } @@ -129,12 +134,9 @@ impl fmt::Display for LoadError { macro_rules! error { ($kind:ident, $desc:expr) => { - return Err( - ::std::convert::From::from( - $crate::error::LoadError::new( - $crate::error::LoadErrorKind::$kind, $desc - ) - ) - ) - } + return Err(::std::convert::From::from($crate::error::LoadError::new( + $crate::error::LoadErrorKind::$kind, + $desc, + ))); + }; } diff --git a/src/lib.rs b/src/lib.rs index 37a01db..7d0527b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,20 +32,24 @@ dome.indices; #![deny(missing_docs)] -#[cfg(feature = "glium-support")] #[macro_use] extern crate glium; +#[cfg(feature = "glium-support")] +#[macro_use] +extern crate glium; extern crate num; extern crate vec_map; -#[macro_use] extern crate serde_derive; +#[macro_use] +extern crate serde_derive; -#[macro_use] mod error; +#[macro_use] +mod error; pub mod raw; +pub use error::{LoadError, LoadErrorKind, ObjError, ObjResult}; use num::{FromPrimitive, Integer}; -use std::io::BufRead; -use std::collections::hash_map::{HashMap, Entry}; use raw::object::Polygon; -pub use error::{ObjResult, ObjError, LoadError, LoadErrorKind}; +use std::collections::hash_map::{Entry, HashMap}; +use std::io::BufRead; /// Load a wavefront OBJ file into Rust & OpenGL friendly format. pub fn load_obj, T: BufRead, I>(input: T) -> ObjResult> { @@ -67,20 +71,30 @@ pub struct Obj { impl, I> Obj { /// Create `Obj` from `RawObj` object. pub fn new(raw: raw::RawObj) -> ObjResult { - let (vertices, indices) = try!(FromRawVertex::process(raw.positions, raw.normals, raw.tex_coords, raw.polygons)); + let (vertices, indices) = try!(FromRawVertex::process( + raw.positions, + raw.normals, + raw.tex_coords, + raw.polygons + )); Ok(Obj { name: raw.name, vertices: vertices, - indices: indices + indices: indices, }) } } /// Conversion from `RawObj`'s raw data. -pub trait FromRawVertex : Sized { +pub trait FromRawVertex: Sized { /// Build vertex and index buffer from raw object data. - fn process(vertices: Vec<(f32, f32, f32, f32)>, normals: Vec<(f32, f32, f32)>, tex_coords: Vec<(f32, f32, f32)>, polygons: Vec) -> ObjResult<(Vec, Vec)>; + fn process( + vertices: Vec<(f32, f32, f32, f32)>, + normals: Vec<(f32, f32, f32)>, + tex_coords: Vec<(f32, f32, f32)>, + polygons: Vec, + ) -> ObjResult<(Vec, Vec)>; } /// Vertex data type of `Obj` which contains position and normal data of a vertex. @@ -96,7 +110,12 @@ pub struct Vertex { implement_vertex!(Vertex, position, normal); impl FromRawVertex for Vertex { - fn process(positions: Vec<(f32, f32, f32, f32)>, normals: Vec<(f32, f32, f32)>, _: Vec<(f32, f32, f32)>, polygons: Vec) -> ObjResult<(Vec, Vec)> { + fn process( + positions: Vec<(f32, f32, f32, f32)>, + normals: Vec<(f32, f32, f32)>, + _: Vec<(f32, f32, f32)>, + polygons: Vec, + ) -> ObjResult<(Vec, Vec)> { let mut vb = Vec::with_capacity(polygons.len() * 3); let mut ib = Vec::with_capacity(polygons.len() * 3); { @@ -108,30 +127,42 @@ impl FromRawVertex for Vertex { Entry::Vacant(entry) => { let p = positions[pi]; let n = normals[ni]; - let vertex = Vertex { position: [p.0, p.1, p.2], normal: [n.0, n.1, n.2]}; - let index = I::from_usize(vb.len()).expect("Unable to convert the index from usize"); + let vertex = Vertex { + position: [p.0, p.1, p.2], + normal: [n.0, n.1, n.2], + }; + let index = I::from_usize(vb.len()) + .expect("Unable to convert the index from usize"); vb.push(vertex); entry.insert(index); index } // Cache hit -> use it - Entry::Occupied(entry) => { - *entry.get() - } + Entry::Occupied(entry) => *entry.get(), }; ib.push(index) }; for polygon in polygons { match polygon { - Polygon::P(_) | Polygon::PT(_) => error!(InsufficientData, "Tried to extract normal data which are not contained in the model"), + Polygon::P(_) | Polygon::PT(_) => error!( + InsufficientData, + "Tried to extract normal data which are not contained in the model" + ), Polygon::PN(ref vec) if vec.len() == 3 => { - for &(pi, ni) in vec { map(pi, ni) } + for &(pi, ni) in vec { + map(pi, ni) + } } Polygon::PTN(ref vec) if vec.len() == 3 => { - for &(pi, _, ni) in vec { map(pi, ni) } + for &(pi, _, ni) in vec { + map(pi, ni) + } } - _ => error!(UntriangulatedModel, "Model should be triangulated first to be loaded properly") + _ => error!( + UntriangulatedModel, + "Model should be triangulated first to be loaded properly" + ), } } } @@ -144,31 +175,52 @@ impl FromRawVertex for Vertex { #[derive(Copy, PartialEq, Clone, Debug, Serialize, Deserialize)] pub struct Position { /// Position vector of a vertex. - pub position: [f32; 3] + pub position: [f32; 3], } #[cfg(feature = "glium-support")] implement_vertex!(Position, position); impl FromRawVertex for Position { - fn process(vertices: Vec<(f32, f32, f32, f32)>, _: Vec<(f32, f32, f32)>, _: Vec<(f32, f32, f32)>, polygons: Vec) -> ObjResult<(Vec, Vec)> { - let vb = vertices.into_iter().map(|v| Position { position: [v.0, v.1, v.2] }).collect(); + fn process( + vertices: Vec<(f32, f32, f32, f32)>, + _: Vec<(f32, f32, f32)>, + _: Vec<(f32, f32, f32)>, + polygons: Vec, + ) -> ObjResult<(Vec, Vec)> { + let vb = vertices + .into_iter() + .map(|v| Position { + position: [v.0, v.1, v.2], + }) + .collect(); let mut ib = Vec::with_capacity(polygons.len() * 3); { - let mut map = |pi: usize| { ib.push(I::from_usize(pi).expect("Unable to convert the index from usize")) }; + let mut map = |pi: usize| { + ib.push(I::from_usize(pi).expect("Unable to convert the index from usize")) + }; for polygon in polygons { match polygon { Polygon::P(ref vec) if vec.len() == 3 => { - for &pi in vec { map(pi) } + for &pi in vec { + map(pi) + } } Polygon::PT(ref vec) | Polygon::PN(ref vec) if vec.len() == 3 => { - for &(pi, _) in vec { map(pi) } + for &(pi, _) in vec { + map(pi) + } } Polygon::PTN(ref vec) if vec.len() == 3 => { - for &(pi, _, _) in vec { map(pi) } + for &(pi, _, _) in vec { + map(pi) + } } - _ => error!(UntriangulatedModel, "Model should be triangulated first to be loaded properly") + _ => error!( + UntriangulatedModel, + "Model should be triangulated first to be loaded properly" + ), } } } @@ -184,14 +236,19 @@ pub struct TexturedVertex { /// Normal vertor of a vertex. pub normal: [f32; 3], /// Texture of a vertex. - pub texture: [f32; 3] + pub texture: [f32; 3], } #[cfg(feature = "glium-support")] implement_vertex!(TexturedVertex, position, normal, texture); impl FromRawVertex for TexturedVertex { - fn process(positions: Vec<(f32, f32, f32, f32)>, normals: Vec<(f32, f32, f32)>, tex_coords: Vec<(f32, f32, f32)>, polygons: Vec) -> ObjResult<(Vec, Vec)> { + fn process( + positions: Vec<(f32, f32, f32, f32)>, + normals: Vec<(f32, f32, f32)>, + tex_coords: Vec<(f32, f32, f32)>, + polygons: Vec, + ) -> ObjResult<(Vec, Vec)> { let mut vb = Vec::with_capacity(polygons.len() * 3); let mut ib = Vec::with_capacity(polygons.len() * 3); { @@ -204,16 +261,19 @@ impl FromRawVertex for TexturedVertex { let p = positions[pi]; let n = normals[ni]; let t = tex_coords[ti]; - let vertex = TexturedVertex { position: [p.0, p.1, p.2], normal: [n.0, n.1, n.2], texture: [t.0, t.1, t.2] }; - let index = I::from_usize(vb.len()).expect("Unable to convert the index from usize"); + let vertex = TexturedVertex { + position: [p.0, p.1, p.2], + normal: [n.0, n.1, n.2], + texture: [t.0, t.1, t.2], + }; + let index = I::from_usize(vb.len()) + .expect("Unable to convert the index from usize"); vb.push(vertex); entry.insert(index); index } // Cache hit -> use it - Entry::Occupied(entry) => { - *entry.get() - } + Entry::Occupied(entry) => *entry.get(), }; ib.push(index) }; @@ -235,21 +295,26 @@ impl FromRawVertex for TexturedVertex { } } - #[cfg(feature = "glium-support")] mod glium_support { - use glium::{vertex, index, VertexBuffer, IndexBuffer}; - use glium::backend::Facade; use super::Obj; + use glium::backend::Facade; + use glium::{index, vertex, IndexBuffer, VertexBuffer}; impl Obj { /// Retrieve glium-compatible vertex buffer from Obj - pub fn vertex_buffer(&self, facade: &F) -> Result, vertex::BufferCreationError> { + pub fn vertex_buffer( + &self, + facade: &F, + ) -> Result, vertex::BufferCreationError> { VertexBuffer::new(facade, &self.vertices) } /// Retrieve glium-compatible index buffer from Obj - pub fn index_buffer(&self, facade: &F) -> Result, index::BufferCreationError> { + pub fn index_buffer( + &self, + facade: &F, + ) -> Result, index::BufferCreationError> { IndexBuffer::new(facade, index::PrimitiveType::TrianglesList, &self.indices) } } diff --git a/src/raw/lexer.rs b/src/raw/lexer.rs index 07f8d76..3531a21 100644 --- a/src/raw/lexer.rs +++ b/src/raw/lexer.rs @@ -6,16 +6,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use error::ObjResult; use std; use std::io::prelude::*; -use error::ObjResult; pub fn lex(input: T, mut callback: F) -> ObjResult<()> - where T: BufRead, F: FnMut(&str, &[&str]) -> ObjResult<()> +where + T: BufRead, + F: FnMut(&str, &[&str]) -> ObjResult<()>, { // This is a buffer of the "arguments" for each line, it uses raw pointers // in order to allow it to be re-used across iterations. - let mut args : Vec<*const str> = Vec::new(); + let mut args: Vec<*const str> = Vec::new(); // This is a buffer for continued lines joined by '\'. let mut multi_line = String::new(); @@ -25,9 +27,9 @@ pub fn lex(input: T, mut callback: F) -> ObjResult<()> let line = line.split('#').next().unwrap(); // Remove comments if line.ends_with('\\') { - multi_line.push_str(&line[..line.len()-1]); + multi_line.push_str(&line[..line.len() - 1]); multi_line.push(' '); // Insert a space to delimit the following lines - continue + continue; } multi_line.push_str(line); // Append the current line @@ -45,7 +47,7 @@ pub fn lex(input: T, mut callback: F) -> ObjResult<()> // cleared after the callback returns, meaning the raw pointers don't // outlive the data they're pointing to. unsafe { - let args : &[&str] = std::mem::transmute(&args[..]); + let args: &[&str] = std::mem::transmute(&args[..]); try!(callback(stmt, args)); } // Clear the args buffer for reuse on the next iteration @@ -80,9 +82,16 @@ bmat u 1 -3 3 -1 0 3 -6 3 0 "statement0" => assert_eq!(args, ["arg0", "arg1", "arg2"]), "statement1" => assert_eq!(args, ["arg0", "arg1"]), "statement2" => assert_eq!(args, ["Hello,", "world!"]), - "bmat" => assert_eq!(args, ["u", "1", "-3", "3", "-1", "0", "3", "-6", "3", "0", "0", "3", "-3", "0", "0", "0", "1"]), - _ => panic!("Unit test failed") + "bmat" => assert_eq!( + args, + [ + "u", "1", "-3", "3", "-1", "0", "3", "-6", "3", "0", "0", "3", "-3", "0", "0", + "0", "1" + ] + ), + _ => panic!("Unit test failed"), } Ok(()) - }).is_ok()); + }) + .is_ok()); } diff --git a/src/raw/material.rs b/src/raw/material.rs index f1e65da..f4175eb 100644 --- a/src/raw/material.rs +++ b/src/raw/material.rs @@ -8,8 +8,8 @@ //! Parses `.mtl` format which stores material data -use std::io::prelude::*; use std::collections::HashMap; +use std::io::prelude::*; use std::mem::replace; use error::ObjResult; @@ -48,7 +48,7 @@ pub fn parse_mtl(input: T) -> ObjResult { match args.len() { 1 => name = Some(args[0].to_owned()), - _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument") + _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument"), } } @@ -59,36 +59,26 @@ pub fn parse_mtl(input: T) -> ObjResult { "Ke" => mat.emissive = Some(try!(parse_color(args))), "Km" => unimplemented!(), "Tf" => mat.transmission_filter = Some(try!(parse_color(args))), - "Ns" => { - match args.len() { - 1 => mat.specular_exponent = Some(try!(args[0].parse())), - _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument") - } - } - "Ni" => { - match args.len() { - 1 => mat.optical_density = Some(try!(args[0].parse())), - _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument") - } - } - "illum" => { - match args.len() { - 1 => mat.illumination_model = Some(try!(args[0].parse())), - _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument") - } - } - "d" => { - match args.len() { - 1 => mat.dissolve = Some(try!(args[0].parse())), - _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument") - } - } - "Tr" => { - match args.len() { - 1 => mat.dissolve = Some(1.0 - try!(args[0].parse::())), - _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument") - } - } + "Ns" => match args.len() { + 1 => mat.specular_exponent = Some(try!(args[0].parse())), + _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument"), + }, + "Ni" => match args.len() { + 1 => mat.optical_density = Some(try!(args[0].parse())), + _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument"), + }, + "illum" => match args.len() { + 1 => mat.illumination_model = Some(try!(args[0].parse())), + _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument"), + }, + "d" => match args.len() { + 1 => mat.dissolve = Some(try!(args[0].parse())), + _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument"), + }, + "Tr" => match args.len() { + 1 => mat.dissolve = Some(1.0 - try!(args[0].parse::())), + _ => error!(WrongNumberOfArguments, "Expected exactly 1 argument"), + }, // Texture map statements "map_Ka" => mat.ambient_map = Some(try!(parse_texture_map(args))), @@ -105,7 +95,7 @@ pub fn parse_mtl(input: T) -> ObjResult { "refl" => unimplemented!(), // Unexpected statement - _ => error!(UnexpectedStatement, "Received unknown statement") + _ => error!(UnexpectedStatement, "Received unknown statement"), } Ok(()) @@ -131,24 +121,22 @@ fn parse_color(args: &[&str]) -> ObjResult { match args.len() { 1 => MtlColor::Xyz(args[0], args[0], args[0]), 3 => MtlColor::Xyz(args[0], args[1], args[2]), - _ => error!(WrongNumberOfArguments, "Expected 1 or 3 color values") + _ => error!(WrongNumberOfArguments, "Expected 1 or 3 color values"), } } - "spectral" => { - match args.len() { - 2 => MtlColor::Spectral(args[1].to_owned(), 1.0), - 3 => MtlColor::Spectral(args[1].to_owned(), try!(args[2].parse())), - _ => error!(WrongNumberOfArguments, "Expected 2 or 3 arguments") - } - } + "spectral" => match args.len() { + 2 => MtlColor::Spectral(args[1].to_owned(), 1.0), + 3 => MtlColor::Spectral(args[1].to_owned(), try!(args[2].parse())), + _ => error!(WrongNumberOfArguments, "Expected 2 or 3 arguments"), + }, _ => { let args = f!(args); match args.len() { 1 => MtlColor::Rgb(args[0], args[0], args[0]), 3 => MtlColor::Rgb(args[0], args[1], args[2]), - _ => error!(WrongNumberOfArguments, "Expected 1 or 3 color values") + _ => error!(WrongNumberOfArguments, "Expected 1 or 3 color values"), } } }) @@ -157,7 +145,9 @@ fn parse_color(args: &[&str]) -> ObjResult { /// Parses a texture map specification from the arguments of a statement fn parse_texture_map(args: &[&str]) -> ObjResult { if args.len() == 1 { - Ok(MtlTextureMap { file: args[0].to_owned() }) + Ok(MtlTextureMap { + file: args[0].to_owned(), + }) } else { error!(WrongNumberOfArguments, "Expected exactly 1 argument") } @@ -167,7 +157,7 @@ fn parse_texture_map(args: &[&str]) -> ObjResult { #[derive(Clone, Debug)] pub struct RawMtl { /// Map from the material name to its properties - pub materials: HashMap + pub materials: HashMap, } /// A single material from a `.mtl` file @@ -216,7 +206,7 @@ pub enum MtlColor { /// /// The first argument is the name of a `.rfl` file specifying the curve. /// The second argument is a multiplier for the values in the `.rfl` file. - Spectral(String, f32) + Spectral(String, f32), } /// A texture map specified in a `.mtl` file diff --git a/src/raw/mod.rs b/src/raw/mod.rs index 616d785..96cc890 100644 --- a/src/raw/mod.rs +++ b/src/raw/mod.rs @@ -9,8 +9,8 @@ //! Provides low-level API for Wavefront OBJ format. mod lexer; -pub mod object; pub mod material; +pub mod object; -pub use self::object::{parse_obj, RawObj}; pub use self::material::{parse_mtl, RawMtl}; +pub use self::object::{parse_obj, RawObj}; diff --git a/src/raw/object.rs b/src/raw/object.rs index 1226e4b..bbec9b7 100644 --- a/src/raw/object.rs +++ b/src/raw/object.rs @@ -8,11 +8,11 @@ //! Parses `.obj` format which stores 3D mesh data -use std::io::BufRead; -use std::collections::HashMap; -use vec_map::VecMap; use error::ObjResult; use raw::lexer::lex; +use std::collections::HashMap; +use std::io::BufRead; +use vec_map::VecMap; /// Parses &[&str] into &[f32]. macro_rules! f { @@ -58,10 +58,10 @@ pub fn parse_obj(input: T) -> ObjResult { let mut polygons = Vec::new(); let counter = Counter::new(&points, &lines, &polygons); - let mut group_builder = counter.hash_map("default".to_string()); - let mut mesh_builder = counter.hash_map(String::new()); - let mut smoothing_builder = counter.vec_map(); - let mut merging_builder = counter.vec_map(); + let mut group_builder = counter.hash_map("default".to_string()); + let mut mesh_builder = counter.hash_map(String::new()); + let mut smoothing_builder = counter.vec_map(); + let mut merging_builder = counter.vec_map(); try!(lex(input, |stmt, args| { match stmt { @@ -71,7 +71,7 @@ pub fn parse_obj(input: T) -> ObjResult { positions.push(match args.len() { 4 => (args[0], args[1], args[2], args[3]), 3 => (args[0], args[1], args[2], 1.0), - _ => error!(WrongNumberOfArguments, "Expected 3 or 4 arguments") + _ => error!(WrongNumberOfArguments, "Expected 3 or 4 arguments"), }) } "vt" => { @@ -80,14 +80,14 @@ pub fn parse_obj(input: T) -> ObjResult { 3 => (args[0], args[1], args[2]), 2 => (args[0], args[1], 0.0), 1 => (args[0], 0.0, 0.0), - _ => error!(WrongNumberOfArguments, "Expected 1, 2 or 3 arguments") + _ => error!(WrongNumberOfArguments, "Expected 1, 2 or 3 arguments"), }) } "vn" => { let args = f!(args); normals.push(match args.len() { 3 => (args[0], args[1], args[2]), - _ => error!(WrongNumberOfArguments, "Expected 3 arguments") + _ => error!(WrongNumberOfArguments, "Expected 3 arguments"), }) } "vp" => { @@ -96,7 +96,7 @@ pub fn parse_obj(input: T) -> ObjResult { 3 => (args[0], args[1], args[2]), 2 => (args[0], args[1], 1.0), 1 => (args[0], 0.0, 1.0), - _ => error!(WrongNumberOfArguments, "Expected 1, 2 or 3 arguments") + _ => error!(WrongNumberOfArguments, "Expected 1, 2 or 3 arguments"), }) } @@ -104,9 +104,15 @@ pub fn parse_obj(input: T) -> ObjResult { "cstype" => { let _rational: bool; let geometry = match args.len() { - 2 if args[0] == "rat" => { _rational = true; args[1] } - 1 => { _rational = false; args[0] } - _ => error!(WrongTypeOfArguments, "Expected 'rat xxx' or 'xxx' format") + 2 if args[0] == "rat" => { + _rational = true; + args[1] + } + 1 => { + _rational = false; + args[0] + } + _ => error!(WrongTypeOfArguments, "Expected 'rat xxx' or 'xxx' format"), }; match geometry { @@ -115,7 +121,10 @@ pub fn parse_obj(input: T) -> ObjResult { "bspline" => unimplemented!(), "cardinal" => unimplemented!(), "taylor" => unimplemented!(), - _ => error!(WrongTypeOfArguments, "Expected one of 'bmatrix', 'bezier', 'bspline', 'cardinal' and 'taylor'") + _ => error!( + WrongTypeOfArguments, + "Expected one of 'bmatrix', 'bezier', 'bspline', 'cardinal' and 'taylor'" + ), } } "deg" => { @@ -123,7 +132,7 @@ pub fn parse_obj(input: T) -> ObjResult { match args.len() { 2 => unimplemented!(), // (deg_u, deg_v) 1 => unimplemented!(), // (deg_u) - _ => error!(WrongNumberOfArguments, "Expected 1 or 2 arguments") + _ => error!(WrongNumberOfArguments, "Expected 1 or 2 arguments"), } } "bmat" => unimplemented!(), @@ -132,13 +141,15 @@ pub fn parse_obj(input: T) -> ObjResult { // Elements "p" => { for v in args { - let v : i32 = try!(v.parse()); + let v: i32 = try!(v.parse()); let v = idx!(v, positions); points.push(v); } } "l" => { - if args.len() < 2 { error!(WrongNumberOfArguments, "Expected at least 2 arguments") } + if args.len() < 2 { + error!(WrongNumberOfArguments, "Expected at least 2 arguments") + } let mut args = args.iter(); let first = args.next().unwrap(); let rest = args; @@ -159,29 +170,30 @@ pub fn parse_obj(input: T) -> ObjResult { Line::P(points) } (p, t, 0) => { - let mut points = vec![( - idx!(p, positions), - idx!(t, tex_coords))]; + let mut points = vec![(idx!(p, positions), idx!(t, tex_coords))]; for gs in rest { let group = try!(parse_vertex_group(gs)); if group.2 != 0 { error!(WrongTypeOfArguments, "Unexpected vertex format"); } - points.push(( - idx!(group.0, positions), - idx!(group.1, tex_coords))); + points.push((idx!(group.0, positions), idx!(group.1, tex_coords))); } Line::PT(points) } _ => { - error!(WrongTypeOfArguments, "Unexpected vertex format, expected `#` or `#/#`"); + error!( + WrongTypeOfArguments, + "Unexpected vertex format, expected `#` or `#/#`" + ); } }; lines.push(line); } "fo" | "f" => { - if args.len() < 3 { error!(WrongNumberOfArguments, "Expected at least 3 arguments") } + if args.len() < 3 { + error!(WrongNumberOfArguments, "Expected at least 3 arguments") + } let mut args = args.iter(); let first = args.next().unwrap(); @@ -204,50 +216,41 @@ pub fn parse_obj(input: T) -> ObjResult { Polygon::P(polygon) } (p, t, 0) => { - let mut polygon = vec![( - idx!(p, positions), - idx!(t, tex_coords))]; + let mut polygon = vec![(idx!(p, positions), idx!(t, tex_coords))]; for gs in rest { let group = try!(parse_vertex_group(gs)); if group.2 != 0 { error!(WrongTypeOfArguments, "Unexpected vertex format"); } - polygon.push(( - idx!(group.0, positions), - idx!(group.1, tex_coords))); + polygon.push((idx!(group.0, positions), idx!(group.1, tex_coords))); } Polygon::PT(polygon) } (p, 0, n) => { - let mut polygon = vec![( - idx!(p, positions), - idx!(n, normals))]; + let mut polygon = vec![(idx!(p, positions), idx!(n, normals))]; for gs in rest { let group = try!(parse_vertex_group(gs)); if group.1 != 0 { error!(WrongTypeOfArguments, "Unexpected vertex format"); } - polygon.push(( - idx!(group.0, positions), - idx!(group.2, normals))); + polygon.push((idx!(group.0, positions), idx!(group.2, normals))); } Polygon::PN(polygon) } (p, t, n) => { - let mut polygon = vec![( - idx!(p, positions), - idx!(t, tex_coords), - idx!(n, normals))]; + let mut polygon = + vec![(idx!(p, positions), idx!(t, tex_coords), idx!(n, normals))]; for gs in rest { let group = try!(parse_vertex_group(gs)); polygon.push(( idx!(group.0, positions), idx!(group.1, tex_coords), - idx!(group.2, normals))); + idx!(group.2, normals), + )); } Polygon::PTN(polygon) @@ -272,30 +275,27 @@ pub fn parse_obj(input: T) -> ObjResult { "con" => unimplemented!(), // Grouping - "g" => { - match args.len() { - 1 => group_builder.start(args[0].to_string()), - _ => error!(WrongNumberOfArguments, "Expected group name parameter, but nothing has been supplied") - } - } - "s" => { - match args.len() { - 1 if (args[0] == "off" || args[0] == "0") => smoothing_builder.end(), - 1 => smoothing_builder.start(try!(args[0].parse())), - _ => error!(WrongNumberOfArguments, "Expected only 1 argument") - } - } - "mg" => { - match args.len() { - 1 if (args[0] == "off" || args[0] == "0") => merging_builder.end(), - 1 => merging_builder.start(try!(args[0].parse())), - _ => error!(WrongNumberOfArguments, "Expected only 1 argument") - } - } + "g" => match args.len() { + 1 => group_builder.start(args[0].to_string()), + _ => error!( + WrongNumberOfArguments, + "Expected group name parameter, but nothing has been supplied" + ), + }, + "s" => match args.len() { + 1 if (args[0] == "off" || args[0] == "0") => smoothing_builder.end(), + 1 => smoothing_builder.start(try!(args[0].parse())), + _ => error!(WrongNumberOfArguments, "Expected only 1 argument"), + }, + "mg" => match args.len() { + 1 if (args[0] == "off" || args[0] == "0") => merging_builder.end(), + 1 => merging_builder.start(try!(args[0].parse())), + _ => error!(WrongNumberOfArguments, "Expected only 1 argument"), + }, "o" => { name = match args.len() { 0 => None, - _ => Some(args.join(" ")) + _ => Some(args.join(" ")), } } @@ -304,12 +304,10 @@ pub fn parse_obj(input: T) -> ObjResult { "c_interp" => unimplemented!(), "d_interp" => unimplemented!(), "lod" => unimplemented!(), - "usemtl" => { - match args.len() { - 1 => mesh_builder.start(args[0].to_string()), - _ => error!(WrongNumberOfArguments, "Expected only 1 argument") - } - } + "usemtl" => match args.len() { + 1 => mesh_builder.start(args[0].to_string()), + _ => error!(WrongNumberOfArguments, "Expected only 1 argument"), + }, "mtllib" => { // TODO: .push_all() material_libraries.reserve(args.len()); @@ -323,7 +321,7 @@ pub fn parse_obj(input: T) -> ObjResult { "stech" => unimplemented!(), // Unexpected statement - _ => error!(UnexpectedStatement, "Received unknown statement") + _ => error!(UnexpectedStatement, "Received unknown statement"), } Ok(()) @@ -350,7 +348,7 @@ pub fn parse_obj(input: T) -> ObjResult { groups: group_builder.result, meshes: mesh_builder.result, smoothing_groups: smoothing_builder.result, - merging_groups: merging_builder.result + merging_groups: merging_builder.result, }) } @@ -359,9 +357,9 @@ pub fn parse_obj(input: T) -> ObjResult { fn parse_vertex_group(s: &str) -> ObjResult<(i32, i32, i32)> { let mut indices = s.split('/'); - let first = indices.next().unwrap_or(""); + let first = indices.next().unwrap_or(""); let second = indices.next().unwrap_or(""); - let third = indices.next().unwrap_or(""); + let third = indices.next().unwrap_or(""); let first = try!(first.parse()); let second = if second == "" { @@ -370,36 +368,41 @@ fn parse_vertex_group(s: &str) -> ObjResult<(i32, i32, i32)> { try!(second.parse()) }; - let third = if third == "" { - 0 - } else { - try!(third.parse()) - }; + let third = if third == "" { 0 } else { try!(third.parse()) }; Ok((first, second, third)) } - /// Counts current total count of parsed `points`, `lines` and `polygons`. struct Counter { - points: *const Vec, - lines: *const Vec, - polygons: *const Vec, + points: *const Vec, + lines: *const Vec, + polygons: *const Vec, } impl Counter { /// Constructs a new `Counter`. - fn new(points: *const Vec, lines: *const Vec, polygons: *const Vec) -> Self { + fn new( + points: *const Vec, + lines: *const Vec, + polygons: *const Vec, + ) -> Self { Counter { - points: points, - lines: lines, - polygons: polygons + points: points, + lines: lines, + polygons: polygons, } } /// Returns a current count of parsed `(points, lines, polygons)`. fn get(&self) -> (usize, usize, usize) { - unsafe { ((*self.points).len(), (*self.lines).len(), (*self.polygons).len()) } + unsafe { + ( + (*self.points).len(), + (*self.lines).len(), + (*self.polygons).len(), + ) + } } /// Creates a `HashMap` builder which references `self` as counter. @@ -410,7 +413,7 @@ impl Counter { GroupBuilder { counter: self, current: Some(input), - result: result + result: result, } } @@ -419,37 +422,42 @@ impl Counter { GroupBuilder { counter: self, current: None, - result: VecMap::new() + result: VecMap::new(), } } } - /// Helper for creating `groups`, `meshes`, `smoothing_groups` and `merging_groups` member of /// `Obj`. struct GroupBuilder<'a, T, K> { counter: &'a Counter, current: Option, // Some(K) if some group has been started - // None otherwise - result: T + // None otherwise + result: T, } -impl<'a, T, K> GroupBuilder<'a, T, K> where +impl<'a, T, K> GroupBuilder<'a, T, K> +where T: Map, - K: Clone + Key + K: Clone + Key, { /// Starts a group whose name is `input`. fn start(&mut self, input: K) { let count = self.counter.get(); if let Some(ref current) = self.current { - if *current == input { return } + if *current == input { + return; + } if self.result.get_mut(current).unwrap().end(count) { let res = self.result.remove(¤t); assert!(res.is_some()); } } (|| { - if let Some(ref mut group) = self.result.get_mut(&input) { group.start(count); return } + if let Some(ref mut group) = self.result.get_mut(&input) { + group.start(count); + return; + } let res = self.result.insert(input.clone(), Group::new(count)); assert!(res.is_none()); })(); @@ -459,34 +467,49 @@ impl<'a, T, K> GroupBuilder<'a, T, K> where /// Ends a current group. fn end(&mut self) { if let Some(ref current) = self.current { - if self.result.get_mut(current).unwrap().end(self.counter.get()) { + if self + .result + .get_mut(current) + .unwrap() + .end(self.counter.get()) + { let result = self.result.remove(current); assert!(result.is_some()); } - } else { return } + } else { + return; + } self.current = None; } } - /// Constant which is used to represent undefined bound of range. const UNDEFINED: usize = ::std::usize::MAX; impl Group { fn new(count: (usize, usize, usize)) -> Self { let mut ret = Group { - points: Vec::with_capacity(1), - lines: Vec::with_capacity(1), - polygons: Vec::with_capacity(1) + points: Vec::with_capacity(1), + lines: Vec::with_capacity(1), + polygons: Vec::with_capacity(1), }; ret.start(count); ret } fn start(&mut self, count: (usize, usize, usize)) { - self.points.push(Range { start: count.0, end: UNDEFINED }); - self.lines.push(Range { start: count.1, end: UNDEFINED }); - self.polygons.push(Range { start: count.2, end: UNDEFINED }) + self.points.push(Range { + start: count.0, + end: UNDEFINED, + }); + self.lines.push(Range { + start: count.1, + end: UNDEFINED, + }); + self.polygons.push(Range { + start: count.2, + end: UNDEFINED, + }) } /// Closes group, return true if self is empty @@ -509,7 +532,6 @@ impl Group { } } - /// Custom trait to interface `HashMap` and `VecMap`. trait Map { /// Interface of `insert` function. @@ -521,24 +543,35 @@ trait Map { } impl Map for HashMap { - fn insert(&mut self, k: String, v: V) -> Option { self.insert(k, v) } - fn get_mut(&mut self, k: &String) -> Option<&mut V> { self.get_mut(k) } - fn remove(&mut self, k: &String) -> Option { self.remove(k) } + fn insert(&mut self, k: String, v: V) -> Option { + self.insert(k, v) + } + fn get_mut(&mut self, k: &String) -> Option<&mut V> { + self.get_mut(k) + } + fn remove(&mut self, k: &String) -> Option { + self.remove(k) + } } impl Map for VecMap { - fn insert(&mut self, k: usize, v: V) -> Option { self.insert(k, v) } - fn get_mut(&mut self, k: &usize) -> Option<&mut V> { self.get_mut(*k) } - fn remove(&mut self, k: &usize) -> Option { self.remove(*k) } + fn insert(&mut self, k: usize, v: V) -> Option { + self.insert(k, v) + } + fn get_mut(&mut self, k: &usize) -> Option<&mut V> { + self.get_mut(*k) + } + fn remove(&mut self, k: &usize) -> Option { + self.remove(*k) + } } /// A trait which should be implemented by a type passed into `Key` of `Map`. -trait Key : Eq {} +trait Key: Eq {} impl Key for String {} impl Key for usize {} - /// Low-level Rust binding for `.obj` format. pub struct RawObj { /// Name of the object. @@ -569,7 +602,7 @@ pub struct RawObj { /// Smoothing groups. pub smoothing_groups: VecMap, /// Merging groups. - pub merging_groups: VecMap + pub merging_groups: VecMap, } /// The `Point` type which stores the index of the position vector. @@ -582,7 +615,7 @@ pub enum Line { P(Vec), /// A series of line segments which contain both position and texture coordinate /// data of each vertex - PT(Vec<(usize, usize)>) + PT(Vec<(usize, usize)>), } /// The `Polygon` type. @@ -595,7 +628,7 @@ pub enum Polygon { /// A polygon which contains both position and normal data of each vertex. PN(Vec<(usize, usize)>), /// A polygon which contains all position, texture coordinate and normal data of each vertex. - PTN(Vec<(usize, usize, usize)>) + PTN(Vec<(usize, usize, usize)>), } /// A group which contains ranges of points, lines and polygons @@ -606,15 +639,14 @@ pub struct Group { /// Multiple range of lines pub lines: Vec, /// Multiple range of polygons - pub polygons: Vec + pub polygons: Vec, } - /// A struct which represent `[start, end)` range. #[derive(Copy, PartialEq, Eq, Clone, Debug)] pub struct Range { /// The lower bound of the range (inclusive). pub start: usize, /// The upper bound of the range (exclusive). - pub end: usize + pub end: usize, } diff --git a/tests/obj.rs b/tests/obj.rs index 94ac12d..cf680d7 100644 --- a/tests/obj.rs +++ b/tests/obj.rs @@ -8,12 +8,14 @@ extern crate obj; +use obj::*; use std::fs::File; use std::io::BufReader; -use obj::*; macro_rules! fixture { - ($name:expr) => (BufReader::new(File::open(concat!("tests/fixtures/", $name)).unwrap())) + ($name:expr) => { + BufReader::new(File::open(concat!("tests/fixtures/", $name)).unwrap()) + }; } #[test] @@ -31,8 +33,20 @@ fn normal_cone() { assert_eq!(obj.name, Some("Cone".to_string())); assert_eq!(obj.vertices.len(), 96); - assert_eq!(obj.vertices[0], v!((-0.382682, -1.000000, -0.923880), (-0.259887, 0.445488, -0.856737))); - assert_eq!(obj.vertices[1], v!(( 0.000000, 1.000000, 0.000000), (-0.259887, 0.445488, -0.856737))); + assert_eq!( + obj.vertices[0], + v!( + (-0.382682, -1.000000, -0.923880), + (-0.259887, 0.445488, -0.856737) + ) + ); + assert_eq!( + obj.vertices[1], + v!( + (0.000000, 1.000000, 0.000000), + (-0.259887, 0.445488, -0.856737) + ) + ); assert_eq!(obj.indices.len(), 96); assert_eq!(obj.indices[0], 0); assert_eq!(obj.indices[1], 1); @@ -72,12 +86,54 @@ fn textured_cube() { assert_eq!(obj.name, Some("cube".to_string())); assert_eq!(obj.vertices.len(), 24); dbg!(&obj.vertices); - assert_eq!(obj.vertices[0], vt!((-0.500000, -0.500000, 0.500000), (0.000000, 0.000000, 1.000000), (0.000000, 0.000000, 0.000000))); - assert_eq!(obj.vertices[1], vt!((0.500000, -0.500000, 0.500000), (0.000000, 0.000000, 1.000000), (1.000000, 0.000000, 0.000000))); - assert_eq!(obj.vertices[2], vt!((-0.500000, 0.500000, 0.500000), (0.000000, 0.000000, 1.000000), (0.000000, 1.000000, 0.000000))); - assert_eq!(obj.vertices[3], vt!((0.500000, 0.500000, 0.500000), (0.000000, 0.000000, 1.000000), (1.000000, 1.000000, 0.000000))); - assert_eq!(obj.vertices[4], vt!((-0.500000, 0.500000, 0.500000), (0.000000, 1.000000, 0.000000), (0.000000, 0.000000, 0.000000))); - assert_eq!(obj.vertices[5], vt!((0.500000, 0.500000, 0.500000), (0.000000, 1.000000, 0.000000), (1.000000, 0.000000, 0.000000))); + assert_eq!( + obj.vertices[0], + vt!( + (-0.500000, -0.500000, 0.500000), + (0.000000, 0.000000, 1.000000), + (0.000000, 0.000000, 0.000000) + ) + ); + assert_eq!( + obj.vertices[1], + vt!( + (0.500000, -0.500000, 0.500000), + (0.000000, 0.000000, 1.000000), + (1.000000, 0.000000, 0.000000) + ) + ); + assert_eq!( + obj.vertices[2], + vt!( + (-0.500000, 0.500000, 0.500000), + (0.000000, 0.000000, 1.000000), + (0.000000, 1.000000, 0.000000) + ) + ); + assert_eq!( + obj.vertices[3], + vt!( + (0.500000, 0.500000, 0.500000), + (0.000000, 0.000000, 1.000000), + (1.000000, 1.000000, 0.000000) + ) + ); + assert_eq!( + obj.vertices[4], + vt!( + (-0.500000, 0.500000, 0.500000), + (0.000000, 1.000000, 0.000000), + (0.000000, 0.000000, 0.000000) + ) + ); + assert_eq!( + obj.vertices[5], + vt!( + (0.500000, 0.500000, 0.500000), + (0.000000, 1.000000, 0.000000), + (1.000000, 0.000000, 0.000000) + ) + ); assert_eq!(obj.indices.len(), 36); assert_eq!(obj.indices[0], 0); assert_eq!(obj.indices[1], 1); diff --git a/tests/raw-basics.rs b/tests/raw-basics.rs index 8faba68..dd46f2f 100644 --- a/tests/raw-basics.rs +++ b/tests/raw-basics.rs @@ -8,17 +8,21 @@ extern crate obj; -use obj::raw::{RawObj, parse_obj}; +use obj::raw::{parse_obj, RawObj}; fn fixture(filename: &str) -> RawObj { - use std::path::Path; use std::fs::File; use std::io::BufReader; + use std::path::Path; let path = Path::new("tests").join("fixtures").join(filename); let file = match File::open(&path) { Ok(f) => f, - Err(e) => panic!("Failed to open \"{}\". \x1b[31m{}\x1b[0m", path.to_string_lossy(), e) + Err(e) => panic!( + "Failed to open \"{}\". \x1b[31m{}\x1b[0m", + path.to_string_lossy(), + e + ), }; let input = BufReader::new(file); @@ -72,19 +76,27 @@ macro_rules! test { } macro_rules! eq { - ($lhs:expr, $rhs:expr) => (eq!($lhs, $rhs, stringify!($lhs))); + ($lhs:expr, $rhs:expr) => { + eq!($lhs, $rhs, stringify!($lhs)) + }; - ($lhs:expr, $rhs:expr, $exp:expr) => ({ + ($lhs:expr, $rhs:expr, $exp:expr) => {{ let left = &($lhs); let right = &($rhs); if !((*left == *right) && (*right == *left)) { use std::io::Write; - let _ = writeln!(&mut std::io::stderr(), "\x1b[33m{}\x1b[0m should be \x1b[33m{:?}\x1b[0m, \ - but it was \x1b[33m{:?}\x1b[0m", $exp, *right, *left); + let _ = writeln!( + &mut std::io::stderr(), + "\x1b[33m{}\x1b[0m should be \x1b[33m{:?}\x1b[0m, \ + but it was \x1b[33m{:?}\x1b[0m", + $exp, + *right, + *left + ); panic!($exp); } - }); + }}; } #[test] diff --git a/tests/raw-group.rs b/tests/raw-group.rs index f5ebcd4..a6b03ff 100644 --- a/tests/raw-group.rs +++ b/tests/raw-group.rs @@ -8,10 +8,10 @@ extern crate obj; +use obj::raw::object::Range; +use obj::raw::*; use std::fs::File; use std::io::BufReader; -use obj::raw::*; -use obj::raw::object::Range; macro_rules! test { ($($lhs:expr, $rhs:expr)*) => ({ @@ -20,21 +20,32 @@ macro_rules! test { } macro_rules! eq { - ($lhs:expr, $rhs:expr) => (eq!($lhs, $rhs, stringify!($lhs))); + ($lhs:expr, $rhs:expr) => { + eq!($lhs, $rhs, stringify!($lhs)) + }; - ($lhs:expr, $rhs:expr, $exp:expr) => ({ + ($lhs:expr, $rhs:expr, $exp:expr) => {{ let left = &($lhs); let right = &($rhs); if !((*left == *right) && (*right == *left)) { stderr!(""); - stderr!("{w}{}{c} should be {o}{:?}{c}, but it was {o}{:?}{c}. See {b}{}:{}{c}.", - $exp, *right, *left, line!(), column!(), - w="\x1b[97m", b="\x1b[34m", o="\x1b[33m", c="\x1b[0m"); + stderr!( + "{w}{}{c} should be {o}{:?}{c}, but it was {o}{:?}{c}. See {b}{}:{}{c}.", + $exp, + *right, + *left, + line!(), + column!(), + w = "\x1b[97m", + b = "\x1b[34m", + o = "\x1b[33m", + c = "\x1b[0m" + ); stderr!(""); panic!($exp); } - }); + }}; } macro_rules! stderr { @@ -49,7 +60,7 @@ fn dup_groupnames() { let input = BufReader::new(File::open("tests/fixtures/group.obj").unwrap()); let raw = match parse_obj(input) { Ok(raw) => raw, - Err(e) => panic!(e) + Err(e) => panic!(e), }; test! { diff --git a/tests/raw-material.rs b/tests/raw-material.rs index af95707..9155115 100644 --- a/tests/raw-material.rs +++ b/tests/raw-material.rs @@ -8,17 +8,21 @@ extern crate obj; -use obj::raw::material::{RawMtl, Material, MtlColor, MtlTextureMap, parse_mtl}; +use obj::raw::material::{parse_mtl, Material, MtlColor, MtlTextureMap, RawMtl}; fn fixture(filename: &str) -> RawMtl { - use std::path::Path; use std::fs::File; use std::io::BufReader; + use std::path::Path; let path = Path::new("tests").join("fixtures").join(filename); let file = match File::open(&path) { Ok(f) => f, - Err(e) => panic!("Failed to open \"{}\". \x1b[31m{}\x1b[0m", path.to_string_lossy(), e) + Err(e) => panic!( + "Failed to open \"{}\". \x1b[31m{}\x1b[0m", + path.to_string_lossy(), + e + ), }; let input = BufReader::new(file); @@ -31,17 +35,22 @@ fn cube() { assert_eq!(mtl.materials.len(), 1); let mat = mtl.materials.get("Material").unwrap(); - assert_eq!(mat, &Material { - ambient: Some(MtlColor::Rgb(0.0, 0.0, 0.0)), - diffuse: Some(MtlColor::Rgb(0.64, 0.64, 0.64)), - specular: Some(MtlColor::Rgb(0.5, 0.5, 0.5)), - dissolve: Some(1.0), - specular_exponent: Some(96.078431), - optical_density: Some(1.0), - illumination_model: Some(2), - diffuse_map: Some(MtlTextureMap { file: "cube-uv-num.png".to_owned() }), - ..Material::default() - }); + assert_eq!( + mat, + &Material { + ambient: Some(MtlColor::Rgb(0.0, 0.0, 0.0)), + diffuse: Some(MtlColor::Rgb(0.64, 0.64, 0.64)), + specular: Some(MtlColor::Rgb(0.5, 0.5, 0.5)), + dissolve: Some(1.0), + specular_exponent: Some(96.078431), + optical_density: Some(1.0), + illumination_model: Some(2), + diffuse_map: Some(MtlTextureMap { + file: "cube-uv-num.png".to_owned() + }), + ..Material::default() + } + ); } #[test] @@ -50,25 +59,31 @@ fn untitled() { assert_eq!(mtl.materials.len(), 2); let mat = mtl.materials.get("Material").unwrap(); - assert_eq!(mat, &Material { - ambient: Some(MtlColor::Rgb(0.0, 0.0, 0.0)), - diffuse: Some(MtlColor::Rgb(0.64, 0.64, 0.64)), - specular: Some(MtlColor::Rgb(0.5, 0.5, 0.5)), - dissolve: Some(1.0), - specular_exponent: Some(96.078431), - optical_density: Some(1.0), - illumination_model: Some(2), - ..Material::default() - }); + assert_eq!( + mat, + &Material { + ambient: Some(MtlColor::Rgb(0.0, 0.0, 0.0)), + diffuse: Some(MtlColor::Rgb(0.64, 0.64, 0.64)), + specular: Some(MtlColor::Rgb(0.5, 0.5, 0.5)), + dissolve: Some(1.0), + specular_exponent: Some(96.078431), + optical_density: Some(1.0), + illumination_model: Some(2), + ..Material::default() + } + ); let mat = mtl.materials.get("None").unwrap(); - assert_eq!(mat, &Material { - ambient: Some(MtlColor::Rgb(0.0, 0.0, 0.0)), - diffuse: Some(MtlColor::Rgb(0.8, 0.8, 0.8)), - specular: Some(MtlColor::Rgb(0.8, 0.8, 0.8)), - dissolve: Some(1.0), - specular_exponent: Some(0.0), - illumination_model: Some(2), - ..Material::default() - }); + assert_eq!( + mat, + &Material { + ambient: Some(MtlColor::Rgb(0.0, 0.0, 0.0)), + diffuse: Some(MtlColor::Rgb(0.8, 0.8, 0.8)), + specular: Some(MtlColor::Rgb(0.8, 0.8, 0.8)), + dissolve: Some(1.0), + specular_exponent: Some(0.0), + illumination_model: Some(2), + ..Material::default() + } + ); }