More work on scene parsing.
Using Nom to help with parsing the contents of leaf nodes.
This commit is contained in:
parent
25f8e0782a
commit
38d33ed144
40
Cargo.lock
generated
40
Cargo.lock
generated
|
@ -3,15 +3,16 @@ name = "psychopath"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"docopt 0.6.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 0.6.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nom 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.4.0"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -19,42 +20,48 @@ name = "docopt"
|
||||||
version = "0.6.78"
|
version = "0.6.78"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"regex 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.1.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"strsim 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"strsim 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.4"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "0.1.7"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "1.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "0.1.44"
|
version = "0.1.55"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex-syntax 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.2.2"
|
version = "0.2.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-serialize"
|
name = "rustc-serialize"
|
||||||
version = "0.3.16"
|
version = "0.3.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -62,3 +69,8 @@ name = "strsim"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8-ranges"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
|
|
@ -6,3 +6,4 @@ authors = ["Nathan Vegdahl <cessen@cessen.com>"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
docopt = "0.6"
|
docopt = "0.6"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
|
nom = "1.2"
|
|
@ -1,5 +1,7 @@
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate docopt;
|
extern crate docopt;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate nom;
|
||||||
|
|
||||||
mod math;
|
mod math;
|
||||||
mod algorithm;
|
mod algorithm;
|
||||||
|
|
289
src/parse/basics.rs
Normal file
289
src/parse/basics.rs
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
//! Some basic nom parsers
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
use nom::{IResult, Needed, digit, multispace};
|
||||||
|
use nom::IResult::*;
|
||||||
|
|
||||||
|
|
||||||
|
// Parsers for numbers surrounded by whitespace
|
||||||
|
named!(pub ws_u32<u32>, delimited!(opt!(multispace), u32_utf8, opt!(multispace)));
|
||||||
|
named!(pub ws_u64<u64>, delimited!(opt!(multispace), u64_utf8, opt!(multispace)));
|
||||||
|
named!(pub ws_i32<i32>, delimited!(opt!(multispace), i32_utf8, opt!(multispace)));
|
||||||
|
named!(pub ws_i64<i64>, delimited!(opt!(multispace), i64_utf8, opt!(multispace)));
|
||||||
|
named!(pub ws_f32<f32>, delimited!(opt!(multispace), f32_utf8, opt!(multispace)));
|
||||||
|
named!(pub ws_f64<f64>, delimited!(opt!(multispace), f64_utf8, opt!(multispace)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
|
||||||
|
named!(pub u32_utf8<u32>, chain!(
|
||||||
|
bytes: digit,
|
||||||
|
|| { str::from_utf8(bytes).unwrap().parse::<u32>().unwrap() }
|
||||||
|
));
|
||||||
|
|
||||||
|
named!(pub i32_utf8<i32>, chain!(
|
||||||
|
sign: one_of!("-+")? ~
|
||||||
|
bytes: digit,
|
||||||
|
|| {
|
||||||
|
match sign {
|
||||||
|
Some(s) if s == '-' => -str::from_utf8(bytes).unwrap().parse::<i32>().unwrap(),
|
||||||
|
_ => str::from_utf8(bytes).unwrap().parse::<i32>().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
named!(pub u64_utf8<u64>, chain!(
|
||||||
|
bytes: digit,
|
||||||
|
|| { str::from_utf8(bytes).unwrap().parse::<u64>().unwrap() }
|
||||||
|
));
|
||||||
|
|
||||||
|
named!(pub i64_utf8<i64>, chain!(
|
||||||
|
sign: one_of!("-+")? ~
|
||||||
|
bytes: digit,
|
||||||
|
|| {
|
||||||
|
match sign {
|
||||||
|
Some(s) if s == '-' => -str::from_utf8(bytes).unwrap().parse::<i64>().unwrap(),
|
||||||
|
_ => str::from_utf8(bytes).unwrap().parse::<i64>().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
named!(pub f32_utf8<f32>, chain!(
|
||||||
|
bytes: take_decimal_real,
|
||||||
|
|| {
|
||||||
|
str::from_utf8(bytes).unwrap().parse::<f32>().unwrap()
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
named!(pub f64_utf8<f64>, chain!(
|
||||||
|
bytes: take_decimal_real,
|
||||||
|
|| {
|
||||||
|
str::from_utf8(bytes).unwrap().parse::<f64>().unwrap()
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
fn take_decimal_integer(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||||
|
named!(rr<&[u8], ()>, chain!(
|
||||||
|
one_of!("-+")? ~
|
||||||
|
digit,
|
||||||
|
||{()}
|
||||||
|
));
|
||||||
|
|
||||||
|
match rr(i) {
|
||||||
|
Done(remaining, _) => {
|
||||||
|
let m = i.len() - remaining.len();
|
||||||
|
if m == 0 {
|
||||||
|
Incomplete(Needed::Unknown)
|
||||||
|
} else {
|
||||||
|
Done(&i[m..], &i[0..m])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Error(e) => Error(e),
|
||||||
|
|
||||||
|
Incomplete(e) => Incomplete(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn take_decimal_real(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||||
|
named!(rr<&[u8], ()>, chain!(
|
||||||
|
one_of!("-+")? ~
|
||||||
|
digit ~
|
||||||
|
complete!(chain!(tag!(".") ~ digit, ||{()}))?,
|
||||||
|
||{()}
|
||||||
|
));
|
||||||
|
|
||||||
|
match rr(i) {
|
||||||
|
Done(remaining, _) => {
|
||||||
|
let m = i.len() - remaining.len();
|
||||||
|
if m == 0 {
|
||||||
|
Incomplete(Needed::Unknown)
|
||||||
|
} else {
|
||||||
|
Done(&i[m..], &i[0..m])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Error(e) => Error(e),
|
||||||
|
|
||||||
|
Incomplete(e) => Incomplete(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use nom::IResult;
|
||||||
|
use nom::IResult::*;
|
||||||
|
use super::take_decimal_real;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_u32_1() {
|
||||||
|
assert_eq!(ws_u32(b"42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_u32(b" 42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_u32(b"42 "), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_u32(b" 42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_u32(b" 42 53"), Done(&b"53"[..], 42));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_i32_1() {
|
||||||
|
assert_eq!(ws_i32(b"42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_i32(b" 42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_i32(b"42 "), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_i32(b" 42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_i32(b" 42 53"), Done(&b"53"[..], 42));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_i32_2() {
|
||||||
|
assert_eq!(ws_i32(b"-42"), Done(&b""[..], -42));
|
||||||
|
assert_eq!(ws_i32(b" -42"), Done(&b""[..], -42));
|
||||||
|
assert_eq!(ws_i32(b"-42 "), Done(&b""[..], -42));
|
||||||
|
assert_eq!(ws_i32(b" -42 "), Done(&b""[..], -42));
|
||||||
|
assert_eq!(ws_i32(b" -42 53"), Done(&b"53"[..], -42));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_u64_1() {
|
||||||
|
assert_eq!(ws_u64(b"42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_u64(b" 42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_u64(b"42 "), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_u64(b" 42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_u64(b" 42 53"), Done(&b"53"[..], 42));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_i64_1() {
|
||||||
|
assert_eq!(ws_i64(b"42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_i64(b" 42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_i64(b"42 "), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_i64(b" 42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(ws_i64(b" 42 53"), Done(&b"53"[..], 42));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_i64_2() {
|
||||||
|
assert_eq!(ws_i64(b"-42"), Done(&b""[..], -42));
|
||||||
|
assert_eq!(ws_i64(b" -42"), Done(&b""[..], -42));
|
||||||
|
assert_eq!(ws_i64(b"-42 "), Done(&b""[..], -42));
|
||||||
|
assert_eq!(ws_i64(b" -42 "), Done(&b""[..], -42));
|
||||||
|
assert_eq!(ws_i64(b" -42 53"), Done(&b"53"[..], -42));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_f32_1() {
|
||||||
|
assert_eq!(ws_f32(b"42"), Done(&b""[..], 42.0));
|
||||||
|
assert_eq!(ws_f32(b" 42"), Done(&b""[..], 42.0));
|
||||||
|
assert_eq!(ws_f32(b"42 "), Done(&b""[..], 42.0));
|
||||||
|
assert_eq!(ws_f32(b" 42"), Done(&b""[..], 42.0));
|
||||||
|
assert_eq!(ws_f32(b" 42 53"), Done(&b"53"[..], 42.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_f32_2() {
|
||||||
|
assert_eq!(ws_f32(b"42.5"), Done(&b""[..], 42.5));
|
||||||
|
assert_eq!(ws_f32(b" 42.5"), Done(&b""[..], 42.5));
|
||||||
|
assert_eq!(ws_f32(b"42.5 "), Done(&b""[..], 42.5));
|
||||||
|
assert_eq!(ws_f32(b" 42.5"), Done(&b""[..], 42.5));
|
||||||
|
assert_eq!(ws_f32(b" 42.5 53"), Done(&b"53"[..], 42.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_f32_3() {
|
||||||
|
assert_eq!(ws_f32(b"-42.5"), Done(&b""[..], -42.5));
|
||||||
|
assert_eq!(ws_f32(b" -42.5"), Done(&b""[..], -42.5));
|
||||||
|
assert_eq!(ws_f32(b"-42.5 "), Done(&b""[..], -42.5));
|
||||||
|
assert_eq!(ws_f32(b" -42.5"), Done(&b""[..], -42.5));
|
||||||
|
assert_eq!(ws_f32(b" -42.5 53"), Done(&b"53"[..], -42.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_f64_1() {
|
||||||
|
assert_eq!(ws_f64(b"42"), Done(&b""[..], 42.0));
|
||||||
|
assert_eq!(ws_f64(b" 42"), Done(&b""[..], 42.0));
|
||||||
|
assert_eq!(ws_f64(b"42 "), Done(&b""[..], 42.0));
|
||||||
|
assert_eq!(ws_f64(b" 42"), Done(&b""[..], 42.0));
|
||||||
|
assert_eq!(ws_f64(b" 42 53"), Done(&b"53"[..], 42.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_f64_2() {
|
||||||
|
assert_eq!(ws_f64(b"42.5"), Done(&b""[..], 42.5));
|
||||||
|
assert_eq!(ws_f64(b" 42.5"), Done(&b""[..], 42.5));
|
||||||
|
assert_eq!(ws_f64(b"42.5 "), Done(&b""[..], 42.5));
|
||||||
|
assert_eq!(ws_f64(b" 42.5"), Done(&b""[..], 42.5));
|
||||||
|
assert_eq!(ws_f64(b" 42.5 53"), Done(&b"53"[..], 42.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ws_f64_3() {
|
||||||
|
assert_eq!(ws_f64(b"-42.5"), Done(&b""[..], -42.5));
|
||||||
|
assert_eq!(ws_f64(b" -42.5"), Done(&b""[..], -42.5));
|
||||||
|
assert_eq!(ws_f64(b"-42.5 "), Done(&b""[..], -42.5));
|
||||||
|
assert_eq!(ws_f64(b" -42.5"), Done(&b""[..], -42.5));
|
||||||
|
assert_eq!(ws_f64(b" -42.5 53"), Done(&b"53"[..], -42.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn take_decimal_real_1() {
|
||||||
|
assert_eq!(take_decimal_real(b"-42.3"), Done(&b""[..], &b"-42.3"[..]));
|
||||||
|
assert_eq!(take_decimal_real(b"42.3"), Done(&b""[..], &b"42.3"[..]));
|
||||||
|
assert_eq!(take_decimal_real(b"-42"), Done(&b""[..], &b"-42"[..]));
|
||||||
|
assert_eq!(take_decimal_real(b"+42.3"), Done(&b""[..], &b"+42.3"[..]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn u32_utf8_1() {
|
||||||
|
assert_eq!(u32_utf8(b"42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(u32_utf8(b"-42").is_err(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn i32_utf8_1() {
|
||||||
|
assert_eq!(i32_utf8(b"42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(i32_utf8(b"-42"), Done(&b""[..], -42));
|
||||||
|
assert_eq!(i32_utf8(b"+42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(i32_utf8(b"--42").is_err(), true);
|
||||||
|
assert_eq!(i32_utf8(b"+-42").is_err(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn u64_utf8_1() {
|
||||||
|
assert_eq!(u64_utf8(b"42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(u64_utf8(b"-42").is_err(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn i64_utf8_1() {
|
||||||
|
assert_eq!(i64_utf8(b"42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(i64_utf8(b"-42"), Done(&b""[..], -42));
|
||||||
|
assert_eq!(i64_utf8(b"+42"), Done(&b""[..], 42));
|
||||||
|
assert_eq!(i64_utf8(b"--42").is_err(), true);
|
||||||
|
assert_eq!(i64_utf8(b"+-42").is_err(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn f32_utf8_1() {
|
||||||
|
assert_eq!(f32_utf8(b"-42.3"), Done(&b""[..], -42.3));
|
||||||
|
assert_eq!(f32_utf8(b"+42.3"), Done(&b""[..], 42.3));
|
||||||
|
assert_eq!(f32_utf8(b"42.3"), Done(&b""[..], 42.3));
|
||||||
|
assert_eq!(f32_utf8(b"42"), Done(&b""[..], 42.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn f64_utf8_1() {
|
||||||
|
assert_eq!(f64_utf8(b"-42.3"), Done(&b""[..], -42.3));
|
||||||
|
assert_eq!(f64_utf8(b"+42.3"), Done(&b""[..], 42.3));
|
||||||
|
assert_eq!(f64_utf8(b"42.3"), Done(&b""[..], 42.3));
|
||||||
|
assert_eq!(f64_utf8(b"42"), Done(&b""[..], 42.0));
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,15 +42,62 @@ impl<'a> DataTree<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_first_child_with_type_name(&'a self, type_name: &str) -> Option<&'a DataTree> {
|
||||||
|
if let &DataTree::Internal { ref children, .. } = self {
|
||||||
|
for child in children.iter() {
|
||||||
|
match child {
|
||||||
|
&DataTree::Internal { type_name: tn, .. } => {
|
||||||
|
if tn == type_name {
|
||||||
|
return Some(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&DataTree::Leaf { type_name: tn, .. } => {
|
||||||
|
if tn == type_name {
|
||||||
|
return Some(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn count_children_with_type_name(&self, type_name: &str) -> usize {
|
||||||
|
if let &DataTree::Internal { ref children, .. } = self {
|
||||||
|
let mut count = 0;
|
||||||
|
for child in children.iter() {
|
||||||
|
match child {
|
||||||
|
&DataTree::Internal { type_name: tn, .. } => {
|
||||||
|
if tn == type_name {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&DataTree::Leaf { type_name: tn, .. } => {
|
||||||
|
if tn == type_name {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For unit tests
|
// For unit tests
|
||||||
fn internal_data(&'a self) -> (&'a str, Option<&'a str>, &'a Vec<DataTree<'a>>) {
|
fn internal_data_or_panic(&'a self) -> (&'a str, Option<&'a str>, &'a Vec<DataTree<'a>>) {
|
||||||
if let DataTree::Internal { type_name, ident, ref children } = *self {
|
if let DataTree::Internal { type_name, ident, ref children } = *self {
|
||||||
(type_name, ident, children)
|
(type_name, ident, children)
|
||||||
} else {
|
} else {
|
||||||
panic!("Expected DataTree::Internal, found DataTree::Leaf")
|
panic!("Expected DataTree::Internal, found DataTree::Leaf")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn leaf_data(&'a self) -> (&'a str, &'a str) {
|
fn leaf_data_or_panic(&'a self) -> (&'a str, &'a str) {
|
||||||
if let DataTree::Leaf { type_name, contents } = *self {
|
if let DataTree::Leaf { type_name, contents } = *self {
|
||||||
(type_name, contents)
|
(type_name, contents)
|
||||||
} else {
|
} else {
|
||||||
|
@ -451,13 +498,13 @@ mod tests {
|
||||||
let dt = DataTree::from_str(input).unwrap();
|
let dt = DataTree::from_str(input).unwrap();
|
||||||
|
|
||||||
// Root
|
// Root
|
||||||
let (t, i, c) = dt.internal_data();
|
let (t, i, c) = dt.internal_data_or_panic();
|
||||||
assert_eq!(t, "ROOT");
|
assert_eq!(t, "ROOT");
|
||||||
assert_eq!(i, None);
|
assert_eq!(i, None);
|
||||||
assert_eq!(c.len(), 1);
|
assert_eq!(c.len(), 1);
|
||||||
|
|
||||||
// First (and only) child
|
// First (and only) child
|
||||||
let (t, i, c) = c[0].internal_data();
|
let (t, i, c) = c[0].internal_data_or_panic();
|
||||||
assert_eq!(t, "Thing");
|
assert_eq!(t, "Thing");
|
||||||
assert_eq!(i, None);
|
assert_eq!(i, None);
|
||||||
assert_eq!(c.len(), 0);
|
assert_eq!(c.len(), 0);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
mod data_tree;
|
mod data_tree;
|
||||||
mod psy;
|
mod psy;
|
||||||
|
pub mod basics;
|
||||||
|
|
||||||
pub use self::data_tree::DataTree;
|
pub use self::data_tree::DataTree;
|
||||||
|
|
131
src/parse/psy.rs
131
src/parse/psy.rs
|
@ -1,8 +1,137 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::result::Result;
|
||||||
|
|
||||||
|
use nom;
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
use renderer::Renderer;
|
use renderer::Renderer;
|
||||||
use super::DataTree;
|
use super::DataTree;
|
||||||
|
use super::basics::ws_u32;
|
||||||
|
|
||||||
pub fn parse_frame(tree: &DataTree) -> Renderer {
|
|
||||||
|
/// Takes in a DataTree representing a Scene node and returns
|
||||||
|
/// a renderer.
|
||||||
|
pub fn parse_frame(tree: &DataTree) -> Result<Renderer, ()> {
|
||||||
|
// Verify we have the right number of each section
|
||||||
|
if tree.count_children_with_type_name("Output") != 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
if tree.count_children_with_type_name("RenderSettings") != 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
if tree.count_children_with_type_name("Camera") != 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
if tree.count_children_with_type_name("World") != 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
if tree.count_children_with_type_name("Assembly") != 1 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse output info
|
||||||
|
let output_info = if let &DataTree::Internal{ref children, ..} =
|
||||||
|
tree.get_first_child_with_type_name("Output").unwrap() {
|
||||||
|
let mut found_path = false;
|
||||||
|
let mut path = String::new();
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
match child {
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "Path" => {
|
||||||
|
// TODO: proper string escaping and quotes stripping
|
||||||
|
found_path = true;
|
||||||
|
path = contents.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "FileFormat" => {
|
||||||
|
// TODO
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "ColorSpace" => {
|
||||||
|
// TODO
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "Dither" => {
|
||||||
|
// TODO
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found_path {
|
||||||
|
(path)
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse render settings
|
||||||
|
let render_settings = if let &DataTree::Internal{ref children, ..} =
|
||||||
|
tree.get_first_child_with_type_name("RenderSettings").unwrap() {
|
||||||
|
let mut found_res = false;
|
||||||
|
let mut found_spp = false;
|
||||||
|
let mut res = (0, 0);
|
||||||
|
let mut spp = 0;
|
||||||
|
let mut seed = 0;
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
match child {
|
||||||
|
// Resolution
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "Resolution" => {
|
||||||
|
if let IResult::Done(_, (w, h)) = closure!(terminated!(tuple!(ws_u32, ws_u32),
|
||||||
|
nom::eof))(contents.as_bytes()) {
|
||||||
|
found_res = true;
|
||||||
|
res = (w, h);
|
||||||
|
} else {
|
||||||
|
// Found Resolution, but its contents is not in the right format
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "SamplesPerPixel" => {
|
||||||
|
if let IResult::Done(_, n) = ws_u32(contents.as_bytes()) {
|
||||||
|
found_spp = true;
|
||||||
|
spp = n;
|
||||||
|
} else {
|
||||||
|
// Found SamplesPerPixel, but its contents is not in the right format
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&DataTree::Leaf { type_name, contents } if type_name == "Seed" => {
|
||||||
|
if let IResult::Done(_, n) = ws_u32(contents.as_bytes()) {
|
||||||
|
seed = n;
|
||||||
|
} else {
|
||||||
|
// Found Seed, but its contents is not in the right format
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found_res && found_spp {
|
||||||
|
(res, spp)
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse camera
|
||||||
|
|
||||||
|
// Parse world
|
||||||
|
|
||||||
|
// Parse root scene assembly
|
||||||
|
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use math::fast_logit;
|
||||||
use image::Image;
|
use image::Image;
|
||||||
use surface;
|
use surface;
|
||||||
use surface::Surface;
|
use surface::Surface;
|
||||||
|
use scene::Scene;
|
||||||
|
|
||||||
pub struct Renderer {
|
pub struct Renderer {
|
||||||
pub output_file: String,
|
pub output_file: String,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user