diff --git a/src/bin/tokenize.rs b/src/bin/tokenize.rs deleted file mode 100644 index 9c39605..0000000 --- a/src/bin/tokenize.rs +++ /dev/null @@ -1,49 +0,0 @@ -use nom::bytes::complete::tag; -use nom::bytes::complete::take_until1; -use nom::sequence::tuple; - -fn main() { - todo!() -} - -#[derive(Debug, PartialEq)] -enum Token { - Tag(String), - Str(String), - Num(f32), -} - -fn tokenize(line: &str) -> Vec { - line.split(" ") - .map(|piece| { - if let Ok(n) = piece.parse::() { - Token::Num(n) - } else if let Ok((_, (_, s, _))) = tuple(( - tag::<&str, &str, ()>("\""), - take_until1("\""), - tag::<&str, &str, ()>("\""), - ))(piece) - { - Token::Str(s.into()) - } else { - Token::Tag(piece.into()) - } - }) - .collect() -} - -#[test] -fn test_tokenize() { - let line = "foo \"bar\" 1.23 baz \"asdf\" etc"; - assert_eq!( - tokenize(line), - vec![ - Token::Tag("foo".into()), - Token::Str("bar".into()), - Token::Num(1.23), - Token::Tag("baz".into()), - Token::Str("asdf".into()), - Token::Tag("etc".into()) - ] - ); -} diff --git a/src/parser.rs b/src/parser.rs index d281aba..0d96b17 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -20,68 +20,74 @@ impl From>> for SaveEntityParseError { } } -fn parse_bool(i: &str) -> IResult<&str, bool> { - alt((tag("true"), tag("false")))(i).map(|(s, val)| match val { - "true" => (s, true), - "false" => (s, false), - _ => panic!("Bools must be `true` or `false`!"), - }) -} -fn parse_xyz(i: &str) -> IResult<&str, (f32, f32, f32)> { - tuple((float, space1, float, space1, float))(i).map(|(s, (x, _, y, _, z))| (s, (x, y, z))) +#[derive(Debug, PartialEq)] +enum Token { + Tag(String), + Str(String), + Num(f32), } -fn parse_wxyz(i: &str) -> IResult<&str, (f32, f32, f32, f32)> { - tuple((float, space1, float, space1, float, space1, float))(i) - .map(|(s, (w, _, x, _, y, _, z))| (s, (w, x, y, z))) +/// +/// Simple function to tokenize a string into an array of Token values +/// +pub(crate) fn tokenize(line: &str) -> Vec { + line.split(" ") + .map(|piece| { + if let Ok(n) = piece.parse::() { + Token::Num(n) + } else if let Ok((_, (_, s, _))) = tuple(( + tag::<&str, &str, ()>("\""), + take_until1("\""), + tag::<&str, &str, ()>("\""), + ))(piece) + { + Token::Str(s.into()) + } else { + Token::Tag(piece.into()) + } + }) + .collect() } -fn parse_string(i: &str) -> IResult<&str, &str> { - let (rem, (_, out, _)) = tuple((tag("\""), take_until1("\""), tag("\"")))(i)?; - Ok((rem, out)) +#[test] +fn test_tokenize() { + let line = "foo \"bar\" 1.23 baz \"asdf\" etc"; + assert_eq!( + tokenize(line), + vec![ + Token::Tag("foo".into()), + Token::Str("bar".into()), + Token::Num(1.23), + Token::Tag("baz".into()), + Token::Str("asdf".into()), + Token::Tag("etc".into()) + ] + ); } + /// /// Returns reflected `Transform` /// -pub(crate) fn parse_save_transform(line: &str) -> Result, SaveEntityParseError> { - let (rem, _) = tag("transform")(line)?; - +pub(crate) fn parse_save_transform(tokens: &Vec) -> Result, SaveEntityParseError> { let mut transform = Transform::default(); - let mut curr = rem.trim_start(); - for _ in 0..3 { - if let Ok((rem, (_, _, (x, y, z)))) = - tuple((tag("translation"), space1, parse_xyz))(curr.trim_start()) - { - transform.translation = Vec3::new(x, y, z); - curr = rem.trim_start(); - } else if let Ok((rem, (_, _, (x, y, z, w)))) = - tuple((tag("rotation"), space1, parse_wxyz))(curr.trim_start()) - { - transform.rotation = Quat::from_xyzw(x, y, z, w); - curr = rem.trim_start(); - } else if let Ok((rem, (_, _, (x, y, z)))) = - tuple((tag("scale"), space1, parse_xyz))(curr.trim_start()) - { - transform.scale = Vec3::new(x, y, z); - curr = rem.trim_start(); - } else { - return Err(SaveEntityParseError::Transform); - } - } + // Tag(Transform), + // Tag(Translation), Number, Number, Number + // Tag(Rotation), Number, Number, Number, Number + // Tag(Scale), Number, Number, Number - // Assert there are no trailing characters on the line - debug_assert_eq!(curr, ""); + // return Err(SaveEntityParseError::Transform); - Ok(transform.clone_value()) + todo!("parse_save_transform"); } #[test] fn test_parse_transform() { let line = "transform translation 1.0 2.0 3.0 rotation 0.1 0.2 0.3 1.0 scale 1.1 1.2 1.3"; - let parsed = parse_save_transform(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_transform(&tokens).unwrap(); let expected = Transform { translation: Vec3::new(1.0, 2.0, 3.0), rotation: Quat::from_xyzw(0.1, 0.2, 0.3, 1.0), @@ -97,22 +103,18 @@ fn test_parse_transform() { /// /// Returns a reflected `Name` /// -pub(crate) fn parse_save_name(line: &str) -> Result, SaveEntityParseError> { - let (remainder, _) = tag("name")(line)?; - let n = remainder.trim().to_string(); - if n.is_empty() { - Err(SaveEntityParseError::Name) - } else { - let name = Name::new(n); - Ok(name.clone_value()) - } +pub(crate) fn parse_save_name(tokens: &Vec) -> Result, SaveEntityParseError> { + todo!("parse_save_name"); + + // Err(SaveEntityParseError::Name) } #[test] fn test_parse_name() { { let line = "name Van"; - let parsed = parse_save_name(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_name(&tokens).unwrap(); let expected = Name::new("Van"); assert!(expected @@ -122,7 +124,8 @@ fn test_parse_name() { } { let line = "name Big Mike"; - let parsed = parse_save_name(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_name(&tokens).unwrap(); let expected = Name::new("Big Mike"); assert!(expected @@ -150,23 +153,23 @@ impl Component for SaveModel { /// /// Returns a reflected `SaveModel` /// -pub(crate) fn parse_save_model(line: &str) -> Result, SaveEntityParseError> { - let (rem, (_, _, gltf_path, _, scene_name)) = - tuple((tag("model"), space1, parse_string, space1, parse_string))(line)?; - - debug_assert!(rem == ""); +pub(crate) fn parse_save_model(tokens: &Vec) -> Result, SaveEntityParseError> { + todo!("parse_save_model"); + /* Ok(SaveModel { gltf_file: gltf_path.into(), scene_name: scene_name.into(), } .clone_value()) + */ } #[test] fn test_parse_model() { let line = "model \"models/foo.glb\" \"My Scene\""; - let parsed = parse_save_model(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_model(&tokens).unwrap(); let expected = SaveModel { gltf_file: "models/foo.glb".into(), scene_name: "My Scene".into(), @@ -197,46 +200,19 @@ impl Component for SaveCameraRenderTarget { /// /// Returns a reflected `SaveCameraRenderTarget /// -pub(crate) fn parse_save_camera(line: &str) -> Result, SaveEntityParseError> { - if let Ok((rem, _camera)) = tag::<&str, &str, ()>("camera")(line) { - if let Ok((rem, (_, _target))) = tuple((space1::<&str, ()>, tag("target")))(rem) { - if let Ok((rem, (_, _window))) = tuple((space1::<&str, ()>, tag("window")))(rem) { - // Camera + target + window + UUID - if let Ok((rem, (_, path))) = - tuple((space1::<&str, nom::error::Error<&str>>, parse_string))(rem) - { - debug_assert!(rem == ""); - - Ok(SaveCameraRenderTarget::Window(path.into()).clone_value()) - // Camera + target + widow - } else { - debug_assert!(rem == ""); - - Ok(SaveCameraRenderTarget::Default.clone_value()) - } - // camera + target - } else { - debug_assert!(rem == ""); - - Err(SaveEntityParseError::Camera) - } - // Just camera - } else { - debug_assert!(rem == ""); +pub(crate) fn parse_save_camera(tokens: &Vec) -> Result, SaveEntityParseError> { + todo!("parse_save_camera"); - Ok(SaveCameraRenderTarget::Default.clone_value()) - } // Nothing parsed well - } else { - Err(SaveEntityParseError::Camera) - } + // Err(SaveEntityParseError::Camera) } #[test] fn test_parse_camera() { { let line = "camera"; - let parsed = parse_save_camera(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_camera(&tokens).unwrap(); let expected = SaveCameraRenderTarget::Default; assert!(expected .clone_value() @@ -245,7 +221,8 @@ fn test_parse_camera() { } { let line = "camera target window"; - let parsed = parse_save_camera(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_camera(&tokens).unwrap(); let expected = SaveCameraRenderTarget::Default; assert!(expected .clone_value() @@ -254,12 +231,14 @@ fn test_parse_camera() { } { let line = "camera target"; - let parsed = parse_save_camera(line); + let tokens = tokenize(line); + let parsed = parse_save_camera(&tokens); assert!(parsed.is_err()); } { let line = "camera target window \"some.entity\""; - let parsed = parse_save_camera(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_camera(&tokens).unwrap(); let expected = SaveCameraRenderTarget::Window("some.entity".into()); assert!(expected .clone_value() @@ -268,7 +247,8 @@ fn test_parse_camera() { } { let line = "notcamera"; - let parsed = parse_save_camera(line); + let tokens = tokenize(line); + let parsed = parse_save_camera(&tokens); assert!(parsed.is_err()); } } @@ -295,18 +275,17 @@ impl Component for SaveParent { /// /// Returns a reflected `SaveParent` /// -pub(crate) fn parse_save_parent(line: &str) -> Result, SaveEntityParseError> { - let (rem, (_, _, parent_file)) = tuple((tag("parent"), space1, parse_string))(line)?; - - debug_assert!(rem.is_empty()); +pub(crate) fn parse_save_parent(tokens: &Vec) -> Result, SaveEntityParseError> { + todo!("parse_save_parent"); - Ok(SaveParent(parent_file.into()).clone_value()) + // Ok(SaveParent(parent_file.into()).clone_value()) } #[test] fn test_parse_parent() { let line = "parent \"some_other_file.entity\""; - let parsed = parse_save_parent(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_parent(&tokens).unwrap(); let expected = SaveParent("some_other_file.entity".into()); assert!(expected .clone_value() @@ -320,25 +299,24 @@ fn test_parse_parent() { /// /// Returns a reflected `Window` /// -pub(crate) fn parse_save_window(line: &str) -> Result, SaveEntityParseError> { - let (rem, (_, _, window_title)) = tuple((tag("window"), space1, parse_string))(line)?; - - let (rem, (_, _, _, visibility)) = tuple((space1, tag("visible"), space1, parse_bool))(rem)?; - - debug_assert!(rem.is_empty()); +pub(crate) fn parse_save_window(tokens: &Vec) -> Result, SaveEntityParseError> { + todo!("parse_save_window"); + /* Ok(Window { title: window_title.into(), visible: visibility, ..default() } .clone_value()) + */ } #[test] fn test_parse_window() { let line = "window \"Editor\" visible false"; - let parsed = parse_save_window(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_window(&tokens).unwrap(); let expected = Window { visible: false, title: "Editor".into(), @@ -358,29 +336,24 @@ fn test_parse_window() { /// /// Returns a reflected `Text` /// -pub(crate) fn parse_save_ui_text(line: &str) -> Result, SaveEntityParseError> { - let (rem, (_tag_text, _space1, text)) = tuple((tag("uiText"), space1, parse_string))(line)?; - - let (rem, (_space, _tag_color, _space1, _hash, hex_color)) = - tuple((space1, tag("color"), space1, char('#'), hex_digit1))(rem)?; - - let (rem, (_space, _tag_size, _space1, font_size)) = - tuple((space1, tag("size"), space1, float))(rem)?; - - debug_assert!(rem.is_empty()); +pub(crate) fn parse_save_ui_text(tokens: &Vec) -> Result, SaveEntityParseError> { + todo!("parse_save_ui_text"); + /* let style = TextStyle { color: Color::Srgba(Srgba::hex(hex_color).unwrap()), font_size, ..default() }; Ok(Text::from_section(text, style).clone_value()) + */ } #[test] fn test_save_ui_text() { let line = "uiText \"This is the text\" color #caffee size 14.6"; - let parsed = parse_save_ui_text(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_ui_text(&tokens).unwrap(); let expected = Text::from_section( "This is the text", TextStyle { @@ -402,8 +375,8 @@ fn test_save_ui_text() { pub(crate) fn parse_save_tag( t: &str, ) -> impl FnOnce(&str) -> Result, SaveEntityParseError> + '_ { - move |line: &str| -> Result, SaveEntityParseError> { - Ok(tag(t)(line).map(|_| T::default().clone_value())?) + move |tokens: &Vec| -> Result, SaveEntityParseError> { + todo!("parse_save_tag") } } @@ -414,7 +387,8 @@ struct TestingTag; #[test] fn test_save_tag() { let line = "testing"; - let parsed = parse_save_tag::("testing")(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_tag::("testing")(&tokens).unwrap(); let expected = TestingTag; assert!(expected .clone_value() @@ -441,21 +415,16 @@ impl Component for SaveTargetCamera { /// /// Returns reflected `SaveTargetCamera` pub(crate) fn parse_save_target_camera( - line: &str, + tokens: &Vec, ) -> Result, SaveEntityParseError> { - Ok( - tuple((tag("targetCamera"), space1, parse_string))(line).map( - |(_, (_, _, target_camera_entity_file))| { - SaveTargetCamera(target_camera_entity_file.into()).clone_value() - }, - )?, - ) + todo!("parse_save_target_camera") } #[test] fn test_target_camera() { let line = "targetCamera \"./level-camera.entity\""; - let parsed = parse_save_target_camera(line).unwrap(); + let tokens = tokenize(line); + let parsed = parse_save_target_camera(&tokens).unwrap(); let expected = SaveTargetCamera("./level-camera.entity".into()); assert!(expected diff --git a/src/save.rs b/src/save.rs index 6b85db4..e39e979 100644 --- a/src/save.rs +++ b/src/save.rs @@ -54,9 +54,12 @@ impl SaveEntity { // track if this line matched any components let mut good = false; + // Tokenize the line + let tokens = parser::tokenize(line); + // Run line against all parsers for f in fns { - if let Ok(v) = f(line) { + if let Ok(v) = f(&tokens) { entity.components.push(v); good = true; }