Initial just-get-it-working port of scene paring code to streaming data tree.

It doesn't actually stream yet, just loads the whole parse into
memory, but done via the new streaming code.
This commit is contained in:
Nathan Vegdahl 2020-01-05 23:07:26 +09:00
parent 7f1b1d2382
commit 9c8dd4d882
3 changed files with 193 additions and 582 deletions

View File

@ -1,92 +1,131 @@
#![allow(dead_code)]
use std::{iter::Iterator, result::Result, slice};
use std::{io::Cursor, iter::Iterator, result::Result, slice};
use data_tree::{Event, Parser};
#[derive(Debug, Eq, PartialEq)]
pub enum DataTree<'a> {
pub enum DataTree {
Internal {
type_name: &'a str,
ident: Option<&'a str>,
children: Vec<DataTree<'a>>,
type_name: String,
ident: Option<String>,
children: Vec<DataTree>,
byte_offset: usize,
},
Leaf {
type_name: &'a str,
contents: &'a str,
type_name: String,
contents: String,
byte_offset: usize,
},
}
impl<'a> DataTree<'a> {
pub fn from_str(source_text: &'a str) -> Result<DataTree<'a>, ParseError> {
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum ParseError {
Other(&'static str),
}
// #[derive(Copy, Clone, Eq, PartialEq, Debug)]
// pub enum ParseError {
// MissingOpener(usize),
// MissingOpenInternal(usize),
// MissingCloseInternal(usize),
// MissingOpenLeaf(usize),
// MissingCloseLeaf(usize),
// MissingTypeName(usize),
// UnexpectedIdent(usize),
// UnknownToken(usize),
// Other((usize, &'static str)),
// }
impl<'a> DataTree {
pub fn from_str(source_text: &'a str) -> Result<DataTree, ParseError> {
let mut parser = Parser::new(Cursor::new(source_text));
let mut items = Vec::new();
let mut remaining_text = (0, source_text);
while let Some((item, text)) = parse_node(remaining_text)? {
remaining_text = text;
items.push(item);
loop {
let event = parser.next_event();
println!("{:?}", event);
match event {
Ok(Event::InnerOpen {
type_name,
ident,
byte_offset,
}) => {
let type_name = type_name.into();
let ident = ident.map(|id| id.into());
items.push(parse_node(&mut parser, type_name, ident, byte_offset)?);
}
Ok(Event::Leaf {
type_name,
contents,
byte_offset,
}) => return Err(ParseError::Other("Unexpected leaf value at root level.")),
Ok(Event::InnerClose { .. }) => {
return Err(ParseError::Other("Unexpected closing tag."))
}
Ok(Event::Done) => {
break;
}
Err(_) => return Err(ParseError::Other("Some error happened.")),
}
}
remaining_text = skip_ws_and_comments(remaining_text);
if remaining_text.1.is_empty() {
return Ok(DataTree::Internal {
type_name: "ROOT",
ident: None,
children: items,
byte_offset: 0,
});
} else {
// If the whole text wasn't parsed, something went wrong.
return Err(ParseError::Other((0, "Failed to parse the entire string.")));
}
return Ok(DataTree::Internal {
type_name: "ROOT".into(),
ident: None,
children: items,
byte_offset: 0,
});
}
pub fn type_name(&'a self) -> &'a str {
match *self {
match self {
DataTree::Internal { type_name, .. } | DataTree::Leaf { type_name, .. } => type_name,
}
}
pub fn ident(&'a self) -> Option<&'a str> {
match *self {
DataTree::Internal { ident, .. } => ident,
DataTree::Leaf { .. } => None,
match self {
DataTree::Internal {
ident: Some(id), ..
} => Some(id.as_str()),
_ => None,
}
}
pub fn byte_offset(&'a self) -> usize {
match *self {
match self {
DataTree::Internal { byte_offset, .. } | DataTree::Leaf { byte_offset, .. } => {
byte_offset
*byte_offset
}
}
}
pub fn is_internal(&self) -> bool {
match *self {
match self {
DataTree::Internal { .. } => true,
DataTree::Leaf { .. } => false,
}
}
pub fn is_leaf(&self) -> bool {
match *self {
match self {
DataTree::Internal { .. } => false,
DataTree::Leaf { .. } => true,
}
}
pub fn leaf_contents(&'a self) -> Option<&'a str> {
match *self {
match self {
DataTree::Internal { .. } => None,
DataTree::Leaf { contents, .. } => Some(contents),
DataTree::Leaf { contents, .. } => Some(contents.as_str()),
}
}
pub fn iter_children(&'a self) -> slice::Iter<'a, DataTree<'a>> {
if let DataTree::Internal { ref children, .. } = *self {
pub fn iter_children(&'a self) -> slice::Iter<'a, DataTree> {
if let DataTree::Internal { ref children, .. } = self {
children.iter()
} else {
[].iter()
@ -94,7 +133,7 @@ impl<'a> DataTree<'a> {
}
pub fn iter_children_with_type(&'a self, type_name: &'static str) -> DataTreeFilterIter<'a> {
if let DataTree::Internal { ref children, .. } = *self {
if let DataTree::Internal { ref children, .. } = self {
DataTreeFilterIter {
type_name: type_name,
iter: children.iter(),
@ -142,15 +181,15 @@ impl<'a> DataTree<'a> {
}
// For unit tests
fn internal_data_or_panic(&'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>) {
if let DataTree::Internal {
type_name,
ident,
ref ident,
ref children,
..
} = *self
} = self
{
(type_name, ident, children)
(type_name, ident.as_ref().map(|id| id.as_str()), children)
} else {
panic!("Expected DataTree::Internal, found DataTree::Leaf")
}
@ -160,7 +199,7 @@ impl<'a> DataTree<'a> {
type_name,
contents,
..
} = *self
} = self
{
(type_name, contents)
} else {
@ -169,17 +208,64 @@ impl<'a> DataTree<'a> {
}
}
fn parse_node<R: std::io::Read>(
parser: &mut Parser<R>,
type_name: String,
ident: Option<String>,
byte_offset: usize,
) -> Result<DataTree, ParseError> {
let mut children = Vec::new();
loop {
match parser.next_event() {
Ok(Event::InnerOpen {
type_name,
ident,
byte_offset,
}) => {
let type_name = type_name.into();
let ident = ident.map(|id| id.into());
children.push(parse_node(parser, type_name, ident, byte_offset)?);
}
Ok(Event::Leaf {
type_name,
contents,
byte_offset,
}) => {
children.push(DataTree::Leaf {
type_name: type_name.into(),
contents: contents.into(),
byte_offset: byte_offset,
});
}
Ok(Event::InnerClose { .. }) => break,
Ok(Event::Done) => {
return Err(ParseError::Other("Unexpected end of contents."));
}
Err(_) => {
return Err(ParseError::Other("Some error happened."));
}
}
}
Ok(DataTree::Internal {
type_name: type_name,
ident: ident,
children: children,
byte_offset: byte_offset,
})
}
/// An iterator over the children of a `DataTree` node that filters out the
/// children not matching a specified type name.
pub struct DataTreeFilterIter<'a> {
type_name: &'a str,
iter: slice::Iter<'a, DataTree<'a>>,
iter: slice::Iter<'a, DataTree>,
}
impl<'a> Iterator for DataTreeFilterIter<'a> {
type Item = &'a DataTree<'a>;
type Item = &'a DataTree;
fn next(&mut self) -> Option<&'a DataTree<'a>> {
fn next(&mut self) -> Option<&'a DataTree> {
loop {
if let Some(dt) = self.iter.next() {
if dt.type_name() == self.type_name {
@ -199,29 +285,34 @@ impl<'a> Iterator for DataTreeFilterIter<'a> {
/// type name.
pub struct DataTreeFilterInternalIter<'a> {
type_name: &'a str,
iter: slice::Iter<'a, DataTree<'a>>,
iter: slice::Iter<'a, DataTree>,
}
impl<'a> Iterator for DataTreeFilterInternalIter<'a> {
type Item = (&'a str, Option<&'a str>, &'a Vec<DataTree<'a>>, usize);
type Item = (&'a str, Option<&'a str>, &'a Vec<DataTree>, usize);
fn next(&mut self) -> Option<(&'a str, Option<&'a str>, &'a Vec<DataTree<'a>>, usize)> {
fn next(&mut self) -> Option<(&'a str, Option<&'a str>, &'a Vec<DataTree>, usize)> {
loop {
match self.iter.next() {
Some(&DataTree::Internal {
Some(DataTree::Internal {
type_name,
ident,
ref children,
children,
byte_offset,
}) => {
if type_name == self.type_name {
return Some((type_name, ident, children, byte_offset));
return Some((
type_name,
ident.as_ref().map(|id| id.as_str()),
children,
*byte_offset,
));
} else {
continue;
}
}
Some(&DataTree::Leaf { .. }) => {
Some(DataTree::Leaf { .. }) => {
continue;
}
@ -238,7 +329,7 @@ impl<'a> Iterator for DataTreeFilterInternalIter<'a> {
/// type name.
pub struct DataTreeFilterLeafIter<'a> {
type_name: &'a str,
iter: slice::Iter<'a, DataTree<'a>>,
iter: slice::Iter<'a, DataTree>,
}
impl<'a> Iterator for DataTreeFilterLeafIter<'a> {
@ -247,17 +338,17 @@ impl<'a> Iterator for DataTreeFilterLeafIter<'a> {
fn next(&mut self) -> Option<(&'a str, &'a str, usize)> {
loop {
match self.iter.next() {
Some(&DataTree::Internal { .. }) => {
Some(DataTree::Internal { .. }) => {
continue;
}
Some(&DataTree::Leaf {
Some(DataTree::Leaf {
type_name,
contents,
byte_offset,
}) => {
if type_name == self.type_name {
return Some((type_name, contents, byte_offset));
return Some((type_name, contents, *byte_offset));
} else {
continue;
}
@ -270,480 +361,3 @@ impl<'a> Iterator for DataTreeFilterLeafIter<'a> {
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum ParseError {
MissingOpener(usize),
MissingOpenInternal(usize),
MissingCloseInternal(usize),
MissingOpenLeaf(usize),
MissingCloseLeaf(usize),
MissingTypeName(usize),
UnexpectedIdent(usize),
UnknownToken(usize),
Other((usize, &'static str)),
}
// ================================================================
#[derive(Debug, PartialEq, Eq)]
enum Token<'a> {
OpenInner,
CloseInner,
OpenLeaf,
CloseLeaf,
TypeName(&'a str),
Ident(&'a str),
End,
Unknown,
}
type ParseResult<'a> = Result<Option<(DataTree<'a>, (usize, &'a str))>, ParseError>;
fn parse_node<'a>(source_text: (usize, &'a str)) -> ParseResult<'a> {
let (token, text1) = next_token(source_text);
if let Token::TypeName(type_name) = token {
match next_token(text1) {
// Internal with name
(Token::Ident(n), text2) => {
if let (Token::OpenInner, text3) = next_token(text2) {
let mut children = Vec::new();
let mut text_remaining = text3;
while let Some((node, text4)) = parse_node(text_remaining)? {
text_remaining = text4;
children.push(node);
}
if let (Token::CloseInner, text4) = next_token(text_remaining) {
return Ok(Some((
DataTree::Internal {
type_name: type_name,
ident: Some(n),
children: children,
byte_offset: text1.0,
},
text4,
)));
} else {
return Err(ParseError::MissingCloseInternal(text_remaining.0));
}
} else {
return Err(ParseError::MissingOpenInternal(text2.0));
}
}
// Internal without name
(Token::OpenInner, text2) => {
let mut children = Vec::new();
let mut text_remaining = text2;
while let Some((node, text3)) = parse_node(text_remaining)? {
text_remaining = text3;
children.push(node);
}
if let (Token::CloseInner, text3) = next_token(text_remaining) {
return Ok(Some((
DataTree::Internal {
type_name: type_name,
ident: None,
children: children,
byte_offset: text1.0,
},
text3,
)));
} else {
return Err(ParseError::MissingCloseInternal(text_remaining.0));
}
}
// Leaf
(Token::OpenLeaf, text2) => {
let (contents, text3) = parse_leaf_content(text2);
if let (Token::CloseLeaf, text4) = next_token(text3) {
return Ok(Some((
DataTree::Leaf {
type_name: type_name,
contents: contents,
byte_offset: text1.0,
},
text4,
)));
} else {
return Err(ParseError::MissingCloseLeaf(text3.0));
}
}
// Other
_ => {
return Err(ParseError::MissingOpener(text1.0));
}
}
} else {
return Ok(None);
}
}
fn parse_leaf_content(source_text: (usize, &str)) -> (&str, (usize, &str)) {
let mut si = 1;
let mut escaped = false;
let mut reached_end = true;
for (i, c) in source_text.1.char_indices() {
si = i;
if escaped {
escaped = false;
} else if c == '\\' {
escaped = true;
} else if c == ']' {
reached_end = false;
break;
}
}
if reached_end {
si = source_text.1.len();
}
return (
&source_text.1[0..si],
(source_text.0 + si, &source_text.1[si..]),
);
}
fn next_token<'a>(source_text: (usize, &'a str)) -> (Token<'a>, (usize, &'a str)) {
let text1 = skip_ws_and_comments(source_text);
if let Some(c) = text1.1.chars().nth(0) {
let text2 = (text1.0 + c.len_utf8(), &text1.1[c.len_utf8()..]);
match c {
'{' => {
return (Token::OpenInner, text2);
}
'}' => {
return (Token::CloseInner, text2);
}
'[' => {
return (Token::OpenLeaf, text2);
}
']' => {
return (Token::CloseLeaf, text2);
}
'$' => {
// Parse name
let mut si = 1;
let mut escaped = false;
let mut reached_end = true;
for (i, c) in text1.1.char_indices().skip(1) {
si = i;
if escaped {
escaped = false;
} else if c == '\\' {
escaped = true;
} else if !is_ident_char(c) {
reached_end = false;
break;
}
}
if reached_end {
si = text1.1.len();
}
return (
Token::Ident(&text1.1[0..si]),
(text1.0 + si, &text1.1[si..]),
);
}
_ => {
if is_ident_char(c) {
// Parse type
let mut si = 0;
let mut reached_end = true;
for (i, c) in text1.1.char_indices() {
si = i;
if !is_ident_char(c) {
reached_end = false;
break;
}
}
if reached_end {
si = text1.1.len();
}
return (
Token::TypeName(&text1.1[0..si]),
(text1.0 + si, &text1.1[si..]),
);
}
}
}
} else {
return (Token::End, text1);
}
return (Token::Unknown, text1);
}
fn is_ws(c: char) -> bool {
match c {
'\n' | '\r' | '\t' | ' ' => true,
_ => false,
}
}
fn is_nl(c: char) -> bool {
match c {
'\n' | '\r' => true,
_ => false,
}
}
fn is_reserved_char(c: char) -> bool {
match c {
'{' | '}' | '[' | ']' | '$' | '#' | '\\' => true,
_ => false,
}
}
fn is_ident_char(c: char) -> bool {
// Anything that isn't whitespace or a reserved character
!is_ws(c) && !is_reserved_char(c)
}
fn skip_ws(text: &str) -> &str {
let mut si = 0;
let mut reached_end = true;
for (i, c) in text.char_indices() {
si = i;
if !is_ws(c) {
reached_end = false;
break;
}
}
if reached_end {
si = text.len();
}
return &text[si..];
}
fn skip_comment(text: &str) -> &str {
let mut si = 0;
if Some('#') == text.chars().nth(0) {
let mut reached_end = true;
for (i, c) in text.char_indices() {
si = i;
if is_nl(c) {
reached_end = false;
break;
}
}
if reached_end {
si = text.len();
}
}
return &text[si..];
}
fn skip_ws_and_comments(text: (usize, &str)) -> (usize, &str) {
let mut remaining_text = text.1;
loop {
let tmp = skip_comment(skip_ws(remaining_text));
if tmp.len() == remaining_text.len() {
break;
} else {
remaining_text = tmp;
}
}
let offset = text.0 + text.1.len() - remaining_text.len();
return (offset, remaining_text);
}
// ================================================================
#[cfg(test)]
mod tests {
use super::*;
use super::{next_token, Token};
#[test]
fn tokenize_1() {
let input = (0, "Thing");
assert_eq!(next_token(input), (Token::TypeName("Thing"), (5, "")));
}
#[test]
fn tokenize_2() {
let input = (0, " \n# gdfgdf gfdg dggdf\\sg dfgsd \n Thing");
assert_eq!(next_token(input), (Token::TypeName("Thing"), (41, "")));
}
#[test]
fn tokenize_3() {
let input1 = (0, " Thing { }");
let (token1, input2) = next_token(input1);
let (token2, input3) = next_token(input2);
let (token3, input4) = next_token(input3);
assert_eq!((token1, input2.1), (Token::TypeName("Thing"), " { }"));
assert_eq!((token2, input3.1), (Token::OpenInner, " }"));
assert_eq!((token3, input4.1), (Token::CloseInner, ""));
}
#[test]
fn tokenize_4() {
let input = (0, " $hi_there ");
assert_eq!(next_token(input), (Token::Ident("$hi_there"), (10, " ")));
}
#[test]
fn tokenize_5() {
let input = (0, " $hi\\ t\\#he\\[re ");
assert_eq!(
next_token(input),
(Token::Ident("$hi\\ t\\#he\\[re"), (15, " "),)
);
}
#[test]
fn tokenize_6() {
let input1 = (0, " $hi the[re");
let (token1, input2) = next_token(input1);
let (token2, input3) = next_token(input2);
let (token3, input4) = next_token(input3);
let (token4, input5) = next_token(input4);
let (token5, input6) = next_token(input5);
assert_eq!((token1, input2), (Token::Ident("$hi"), (4, " the[re")));
assert_eq!((token2, input3), (Token::TypeName("the"), (8, "[re")));
assert_eq!((token3, input4), (Token::OpenLeaf, (9, "re")));
assert_eq!((token4, input5), (Token::TypeName("re"), (11, "")));
assert_eq!((token5, input6), (Token::End, (11, "")));
}
#[test]
fn tokenize_7() {
let input1 = (0, "Thing $yar { # A comment\n\tThing2 []\n}");
let (token1, input2) = next_token(input1);
let (token2, input3) = next_token(input2);
let (token3, input4) = next_token(input3);
let (token4, input5) = next_token(input4);
let (token5, input6) = next_token(input5);
let (token6, input7) = next_token(input6);
let (token7, input8) = next_token(input7);
let (token8, input9) = next_token(input8);
assert_eq!(
(token1, input2),
(
Token::TypeName("Thing"),
(5, " $yar { # A comment\n\tThing2 []\n}",)
)
);
assert_eq!(
(token2, input3),
(
Token::Ident("$yar"),
(10, " { # A comment\n\tThing2 []\n}",)
)
);
assert_eq!(
(token3, input4),
(Token::OpenInner, (12, " # A comment\n\tThing2 []\n}",))
);
assert_eq!(
(token4, input5),
(Token::TypeName("Thing2"), (32, " []\n}"))
);
assert_eq!((token5, input6), (Token::OpenLeaf, (34, "]\n}")));
assert_eq!((token6, input7), (Token::CloseLeaf, (35, "\n}")));
assert_eq!((token7, input8), (Token::CloseInner, (37, "")));
assert_eq!((token8, input9), (Token::End, (37, "")));
}
#[test]
fn parse_1() {
let input = r#"
Thing {}
"#;
let dt = DataTree::from_str(input).unwrap();
// Root
let (t, i, c) = dt.internal_data_or_panic();
assert_eq!(t, "ROOT");
assert_eq!(i, None);
assert_eq!(c.len(), 1);
// First (and only) child
let (t, i, c) = c[0].internal_data_or_panic();
assert_eq!(t, "Thing");
assert_eq!(i, None);
assert_eq!(c.len(), 0);
}
#[test]
fn iter_1() {
let dt = DataTree::from_str(
r#"
A {}
B {}
A []
A {}
B {}
"#,
)
.unwrap();
let i = dt.iter_children_with_type("A");
assert_eq!(i.count(), 3);
}
#[test]
fn iter_2() {
let dt = DataTree::from_str(
r#"
A {}
B {}
A []
A {}
B {}
"#,
)
.unwrap();
let i = dt.iter_internal_children_with_type("A");
assert_eq!(i.count(), 2);
}
#[test]
fn iter_3() {
let dt = DataTree::from_str(
r#"
A []
B {}
A {}
A []
B {}
"#,
)
.unwrap();
let i = dt.iter_leaf_children_with_type("A");
assert_eq!(i.count(), 2);
}
}

View File

@ -100,10 +100,7 @@ fn line_count_to_byte_offset(text: &str, offset: usize) -> usize {
}
/// Takes in a `DataTree` representing a Scene node and returns
pub fn parse_scene<'a>(
arena: &'a Arena,
tree: &'a DataTree,
) -> Result<Scene<'a>, PsyParseError> {
pub fn parse_scene<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result<Scene<'a>, PsyParseError> {
// Verify we have the right number of each section
if tree.iter_children_with_type("Output").count() != 1 {
let count = tree.iter_children_with_type("Output").count();
@ -187,9 +184,9 @@ pub fn parse_scene<'a>(
)?;
// Put scene together
let scene_name = if let DataTree::Internal { ident, .. } = *tree {
let scene_name = if let DataTree::Internal { ident, .. } = tree {
if let Some(name) = ident {
Some(name.to_string())
Some(name.clone())
} else {
None
}
@ -224,7 +221,7 @@ fn parse_output_info(tree: &DataTree) -> Result<String, PsyParseError> {
let mut path = String::new();
for child in children {
match *child {
match child {
DataTree::Leaf {
type_name,
contents,
@ -234,14 +231,14 @@ fn parse_output_info(tree: &DataTree) -> Result<String, PsyParseError> {
let tc = contents.trim();
if tc.chars().count() < 2 {
return Err(PsyParseError::IncorrectLeafData(
byte_offset,
*byte_offset,
"File path format is \
incorrect.",
));
}
if tc.chars().nth(0).unwrap() != '"' || !tc.ends_with('"') {
return Err(PsyParseError::IncorrectLeafData(
byte_offset,
*byte_offset,
"File paths must be \
surrounded by quotes.",
));
@ -285,7 +282,7 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
let mut seed = 0;
for child in children {
match *child {
match child {
// Resolution
DataTree::Leaf {
type_name,
@ -293,14 +290,14 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
byte_offset,
} if type_name == "Resolution" => {
if let IResult::Ok((_, (w, h))) =
all_consuming(tuple((ws_u32, ws_u32)))(contents)
all_consuming(tuple((ws_u32, ws_u32)))(&contents)
{
found_res = true;
res = (w, h);
} else {
// Found Resolution, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData(
byte_offset,
*byte_offset,
"Resolution should be specified with two \
integers in the form '[width height]'.",
));
@ -313,13 +310,13 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
contents,
byte_offset,
} if type_name == "SamplesPerPixel" => {
if let IResult::Ok((_, n)) = all_consuming(ws_u32)(contents) {
if let IResult::Ok((_, n)) = all_consuming(ws_u32)(&contents) {
found_spp = true;
spp = n;
} else {
// Found SamplesPerPixel, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData(
byte_offset,
*byte_offset,
"SamplesPerPixel should be \
an integer specified in \
the form '[samples]'.",
@ -333,12 +330,12 @@ fn parse_render_settings(tree: &DataTree) -> Result<((u32, u32), u32, u32), PsyP
contents,
byte_offset,
} if type_name == "Seed" => {
if let IResult::Ok((_, n)) = all_consuming(ws_u32)(contents) {
if let IResult::Ok((_, n)) = all_consuming(ws_u32)(&contents) {
seed = n;
} else {
// Found Seed, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData(
byte_offset,
*byte_offset,
"Seed should be an integer \
specified in the form \
'[samples]'.",
@ -378,19 +375,19 @@ fn parse_camera<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result<Camera<'a>,
// Parse
for child in children.iter() {
match *child {
match child {
// Fov
DataTree::Leaf {
type_name,
contents,
byte_offset,
} if type_name == "Fov" => {
if let IResult::Ok((_, fov)) = all_consuming(ws_f32)(contents) {
if let IResult::Ok((_, fov)) = all_consuming(ws_f32)(&contents) {
fovs.push(fov * (f32::consts::PI / 180.0));
} else {
// Found Fov, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData(
byte_offset,
*byte_offset,
"Fov should be a decimal \
number specified in the \
form '[fov]'.",
@ -404,12 +401,12 @@ fn parse_camera<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result<Camera<'a>,
contents,
byte_offset,
} if type_name == "FocalDistance" => {
if let IResult::Ok((_, fd)) = all_consuming(ws_f32)(contents) {
if let IResult::Ok((_, fd)) = all_consuming(ws_f32)(&contents) {
focus_distances.push(fd);
} else {
// Found FocalDistance, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData(
byte_offset,
*byte_offset,
"FocalDistance should be a \
decimal number specified \
in the form '[fov]'.",
@ -423,12 +420,12 @@ fn parse_camera<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result<Camera<'a>,
contents,
byte_offset,
} if type_name == "ApertureRadius" => {
if let IResult::Ok((_, ar)) = all_consuming(ws_f32)(contents) {
if let IResult::Ok((_, ar)) = all_consuming(ws_f32)(&contents) {
aperture_radii.push(ar);
} else {
// Found ApertureRadius, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData(
byte_offset,
*byte_offset,
"ApertureRadius should be a \
decimal number specified \
in the form '[fov]'.",
@ -442,11 +439,11 @@ fn parse_camera<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result<Camera<'a>,
contents,
byte_offset,
} if type_name == "Transform" => {
if let Ok(mat) = parse_matrix(contents) {
if let Ok(mat) = parse_matrix(&contents) {
mats.push(mat);
} else {
// Found Transform, but its contents is not in the right format
return Err(make_transform_format_error(byte_offset));
return Err(make_transform_format_error(*byte_offset));
}
}
@ -499,7 +496,7 @@ fn parse_world<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result<World<'a>, Ps
));
}
if let DataTree::Leaf { contents, .. } =
*bgs.iter_children_with_type("Type").nth(0).unwrap()
bgs.iter_children_with_type("Type").nth(0).unwrap()
{
contents.trim()
} else {
@ -512,17 +509,17 @@ fn parse_world<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result<World<'a>, Ps
};
match bgs_type {
"Color" => {
if let Some(&DataTree::Leaf {
if let Some(DataTree::Leaf {
contents,
byte_offset,
..
}) = bgs.iter_children_with_type("Color").nth(0)
{
if let Ok(color) = parse_color(contents) {
if let Ok(color) = parse_color(&contents) {
background_color = color;
} else {
return Err(PsyParseError::IncorrectLeafData(
byte_offset,
*byte_offset,
"Color should be specified \
with three decimal numbers \
in the form '[R G B]'.",
@ -548,7 +545,7 @@ fn parse_world<'a>(arena: &'a Arena, tree: &'a DataTree) -> Result<World<'a>, Ps
// Parse light sources
for child in tree.iter_children() {
match *child {
match child {
DataTree::Internal { type_name, .. } if type_name == "DistantDiskLight" => {
lights.push(arena.alloc(parse_distant_disk_light(arena, child)?));
}

View File

@ -28,18 +28,18 @@ pub fn parse_distant_disk_light<'a>(
// Parse
for child in children.iter() {
match *child {
match child {
// Radius
DataTree::Leaf {
type_name,
contents,
byte_offset,
} if type_name == "Radius" => {
if let IResult::Ok((_, radius)) = all_consuming(ws_f32)(contents) {
if let IResult::Ok((_, radius)) = all_consuming(ws_f32)(&contents) {
radii.push(radius);
} else {
// Found radius, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
return Err(PsyParseError::UnknownError(*byte_offset));
}
}
@ -50,12 +50,12 @@ pub fn parse_distant_disk_light<'a>(
byte_offset,
} if type_name == "Direction" => {
if let IResult::Ok((_, direction)) =
all_consuming(tuple((ws_f32, ws_f32, ws_f32)))(contents)
all_consuming(tuple((ws_f32, ws_f32, ws_f32)))(&contents)
{
directions.push(Vector::new(direction.0, direction.1, direction.2));
} else {
// Found direction, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
return Err(PsyParseError::UnknownError(*byte_offset));
}
}
@ -65,11 +65,11 @@ pub fn parse_distant_disk_light<'a>(
contents,
byte_offset,
} if type_name == "Color" => {
if let Ok(color) = parse_color(contents) {
if let Ok(color) = parse_color(&contents) {
colors.push(color);
} else {
// Found color, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
return Err(PsyParseError::UnknownError(*byte_offset));
}
}
@ -93,18 +93,18 @@ pub fn parse_sphere_light<'a>(
// Parse
for child in children.iter() {
match *child {
match child {
// Radius
DataTree::Leaf {
type_name,
contents,
byte_offset,
} if type_name == "Radius" => {
if let IResult::Ok((_, radius)) = all_consuming(ws_f32)(contents) {
if let IResult::Ok((_, radius)) = all_consuming(ws_f32)(&contents) {
radii.push(radius);
} else {
// Found radius, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
return Err(PsyParseError::UnknownError(*byte_offset));
}
}
@ -114,11 +114,11 @@ pub fn parse_sphere_light<'a>(
contents,
byte_offset,
} if type_name == "Color" => {
if let Ok(color) = parse_color(contents) {
if let Ok(color) = parse_color(&contents) {
colors.push(color);
} else {
// Found color, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
return Err(PsyParseError::UnknownError(*byte_offset));
}
}
@ -142,7 +142,7 @@ pub fn parse_rectangle_light<'a>(
// Parse
for child in children.iter() {
match *child {
match child {
// Dimensions
DataTree::Leaf {
type_name,
@ -150,12 +150,12 @@ pub fn parse_rectangle_light<'a>(
byte_offset,
} if type_name == "Dimensions" => {
if let IResult::Ok((_, radius)) =
all_consuming(tuple((ws_f32, ws_f32)))(contents)
all_consuming(tuple((ws_f32, ws_f32)))(&contents)
{
dimensions.push(radius);
} else {
// Found dimensions, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
return Err(PsyParseError::UnknownError(*byte_offset));
}
}
@ -165,11 +165,11 @@ pub fn parse_rectangle_light<'a>(
contents,
byte_offset,
} if type_name == "Color" => {
if let Ok(color) = parse_color(contents) {
if let Ok(color) = parse_color(&contents) {
colors.push(color);
} else {
// Found color, but its contents is not in the right format
return Err(PsyParseError::UnknownError(byte_offset));
return Err(PsyParseError::UnknownError(*byte_offset));
}
}