From cfe3a9ce1715c7c20563503702256ab62463a9b3 Mon Sep 17 00:00:00 2001 From: "Elijah C. Voigt" Date: Sun, 30 Jun 2024 21:49:01 -0700 Subject: [PATCH] Move parsing functions to submodule --- src/save.rs | 275 ++++++++++++++++++++++++++-------------------------- 1 file changed, 140 insertions(+), 135 deletions(-) diff --git a/src/save.rs b/src/save.rs index c8f3384..895d6b7 100644 --- a/src/save.rs +++ b/src/save.rs @@ -21,15 +21,15 @@ struct SaveEntity { } impl SaveEntity { - fn parse(s: &str) -> Result { + fn parse(s: &str) -> Result { let lines = s.split('\n'); let mut entity = SaveEntity { ..default() }; lines.into_iter().for_each(|line| { - if let Ok(name) = parse_save_name(line) { + if let Ok(name) = parse::parse_save_name(line) { entity.name = Some(name); - } else if let Ok(transform) = parse_save_transform(line) { + } else if let Ok(transform) = parse::parse_save_transform(line) { entity.transform = Some(transform); - } else if let Ok(uuid) = parse_save_uuid(line) { + } else if let Ok(uuid) = parse::parse_save_uuid(line) { entity.uuid = Some(uuid); } }); @@ -37,158 +37,163 @@ impl SaveEntity { } } -#[derive(Error, Debug)] -enum SaveEntityParseError { - #[error("Failed to parse Uuid: {0}")] - Uuid(#[from] uuid::Error), - #[error("Failed to parse name")] - Name, - #[error("Failed to parse Transform")] - Transform, - #[error("Failed to parse Entity")] - Nom(nom::Err>>), -} +mod parse { + use super::*; + + #[derive(Error, Debug)] + pub(crate) enum SaveEntityParseError { + #[error("Failed to parse Uuid: {0}")] + Uuid(#[from] uuid::Error), + #[error("Failed to parse name")] + Name, + #[error("Failed to parse Transform")] + Transform, + #[error("Failed to parse Entity")] + Nom(nom::Err>>), + } -// Convert Nom error to parse error -// https://stackoverflow.com/a/77974858/3096574 -impl From>> for SaveEntityParseError { - fn from(err: nom::Err>) -> Self { - SaveEntityParseError::Nom(err.map_input(|input| input.into())) + // Convert Nom error to parse error + // https://stackoverflow.com/a/77974858/3096574 + impl From>> for SaveEntityParseError { + fn from(err: nom::Err>) -> Self { + SaveEntityParseError::Nom(err.map_input(|input| input.into())) + } } -} -fn parse_thing<'a>(s: &'a str, l: &'a str) -> IResult<&'a str, &'a str> { - tag(l)(s) -} + fn parse_thing<'a>(s: &'a str, l: &'a str) -> IResult<&'a str, &'a str> { + tag(l)(s) + } -fn parse_xyz<'a>(i: &'a str) -> IResult<&'a str, (f32, f32, f32)> { - tuple((float, take(1usize), float, take(1usize), float))(i) - .map(|(s, (x, _, y, _, z))| (s, (x, y, z))) -} + fn parse_xyz<'a>(i: &'a str) -> IResult<&'a str, (f32, f32, f32)> { + tuple((float, take(1usize), float, take(1usize), float))(i) + .map(|(s, (x, _, y, _, z))| (s, (x, y, z))) + } -fn parse_wxyz<'a>(i: &'a str) -> IResult<&'a str, (f32, f32, f32, f32)> { - tuple(( - float, - take(1usize), - float, - take(1usize), - float, - take(1usize), - float, - ))(i) - .map(|(s, (w, _, x, _, y, _, z))| (s, (w, x, y, z))) -} + fn parse_wxyz<'a>(i: &'a str) -> IResult<&'a str, (f32, f32, f32, f32)> { + tuple(( + float, + take(1usize), + float, + take(1usize), + float, + take(1usize), + float, + ))(i) + .map(|(s, (w, _, x, _, y, _, z))| (s, (w, x, y, z))) + } -/// -/// ``` -/// let parsed = parse_save_transform("transform translation 1.0 2.0 3.0 rotation 1.0 0.0 0.0 0.0 scale 1.0 1.0 1.0").unwrap(); -/// let expected = Transform { translation: Vec3::new(1.0, 1.0, 1.0), rotation: Quat::from_xzyw(1.0, 0.0, 0.0, 0.0), scale: Vec3::ONE }; -/// -/// assert_eq!(parsed, expected); -/// ``` -/// -fn parse_save_transform(line: &str) -> Result { - let (rem, _) = tag("transform")(line)?; - - let mut transform = Transform::default(); - - let mut curr = rem.trim_start(); - for _ in 0..3 { - if let Ok((input, _)) = parse_thing(curr, "translation") { - let (rem, (x, y, z)) = parse_xyz(input.trim_start())?; - transform.translation = Vec3::new(x, y, z); - curr = rem.trim_start(); - } else if let Ok((input, _)) = parse_thing(curr.trim_start(), "rotation") { - let (rem, (x, y, z, w)) = parse_wxyz(input.trim_start())?; - transform.rotation = Quat::from_xyzw(x, y, z, w); - curr = rem.trim_start(); - } else if let Ok((input, _)) = parse_thing(curr.trim_start(), "scale") { - let (rem, (x, y, z)) = parse_xyz(input.trim_start())?; - transform.scale = Vec3::new(x, y, z); - curr = rem.trim_start(); - } else { - return Err(SaveEntityParseError::Transform); + /// + /// ``` + /// let parsed = parse_save_transform("transform translation 1.0 2.0 3.0 rotation 1.0 0.0 0.0 0.0 scale 1.0 1.0 1.0").unwrap(); + /// let expected = Transform { translation: Vec3::new(1.0, 1.0, 1.0), rotation: Quat::from_xzyw(1.0, 0.0, 0.0, 0.0), scale: Vec3::ONE }; + /// + /// assert_eq!(parsed, expected); + /// ``` + /// + pub(crate) fn parse_save_transform(line: &str) -> Result { + let (rem, _) = tag("transform")(line)?; + + let mut transform = Transform::default(); + + let mut curr = rem.trim_start(); + for _ in 0..3 { + if let Ok((input, _)) = parse_thing(curr, "translation") { + let (rem, (x, y, z)) = parse_xyz(input.trim_start())?; + transform.translation = Vec3::new(x, y, z); + curr = rem.trim_start(); + } else if let Ok((input, _)) = parse_thing(curr.trim_start(), "rotation") { + let (rem, (x, y, z, w)) = parse_wxyz(input.trim_start())?; + transform.rotation = Quat::from_xyzw(x, y, z, w); + curr = rem.trim_start(); + } else if let Ok((input, _)) = parse_thing(curr.trim_start(), "scale") { + let (rem, (x, y, z)) = parse_xyz(input.trim_start())?; + transform.scale = Vec3::new(x, y, z); + curr = rem.trim_start(); + } else { + return Err(SaveEntityParseError::Transform); + } } + + Ok(transform) } - Ok(transform) -} + /// + /// ``` + /// let parsed = parse_save_name("name asfd").unwrap(); + /// let expected = Name::new("asdf"); + /// + /// assert_eq!(parsed, expected); + /// ``` + /// + pub(crate) fn parse_save_name(line: &str) -> Result { + let (remainder, _) = tag("name")(line)?; + let n = remainder.trim().to_string(); + if n.len() == 0 { + Err(SaveEntityParseError::Name) + } else { + let name = Name::new(n); + Ok(name) + } + } -/// -/// ``` -/// let parsed = parse_save_name("name asfd").unwrap(); -/// let expected = Name::new("asdf"); -/// -/// assert_eq!(parsed, expected); -/// ``` -/// -fn parse_save_name(line: &str) -> Result { - let (remainder, _) = tag("name")(line)?; - let n = remainder.trim().to_string(); - if n.len() == 0 { - Err(SaveEntityParseError::Name) - } else { - let name = Name::new(n); - Ok(name) + /// + /// ``` + /// let parsed = parse_save_uuid("uuid 339dd18f-761a-4997-b515-ef57f4dc2447").unwrap(); + /// let expected = Uuid::parse_str("339dd18f-761a-4997-b515-ef57f4dc2447").unwrap(); + /// + /// assert_eq!(parsed, expected); + /// ``` + /// + pub(crate) fn parse_save_uuid(line: &str) -> Result { + let (remainder, _) = tag("uuid")(line)?; + let uuid = Uuid::try_parse(remainder.trim())?; + Ok(uuid) } -} -/// -/// ``` -/// let parsed = parse_save_uuid("uuid 339dd18f-761a-4997-b515-ef57f4dc2447").unwrap(); -/// let expected = Uuid::parse_str("339dd18f-761a-4997-b515-ef57f4dc2447").unwrap(); -/// -/// assert_eq!(parsed, expected); -/// ``` -/// -fn parse_save_uuid(line: &str) -> Result { - let (remainder, _) = tag("uuid")(line)?; - let uuid = Uuid::try_parse(remainder.trim())?; - Ok(uuid) -} + mod test { + use super::*; -mod test { - use super::*; + #[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 expected = Transform { + translation: Vec3::new(1.0, 2.0, 3.0), + rotation: Quat::from_xyzw(0.1, 0.2, 0.3, 1.0), + scale: Vec3::new(1.1, 1.2, 1.3), + }; - #[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 expected = Transform { - translation: Vec3::new(1.0, 2.0, 3.0), - rotation: Quat::from_xyzw(0.1, 0.2, 0.3, 1.0), - scale: Vec3::new(1.1, 1.2, 1.3), - }; + assert_eq!(parsed, expected); + } - assert_eq!(parsed, expected); - } + #[test] + fn test_parse_name() { + { + let line = "name Van"; + let parsed = parse_save_name(line).unwrap(); + let expected = Name::new("Van"); - #[test] - fn test_parse_name() { - { - let line = "name Van"; - let parsed = parse_save_name(line).unwrap(); - let expected = Name::new("Van"); + assert_eq!(parsed, expected); + } + { + let line = "name Big Mike"; + let parsed = parse_save_name(line).unwrap(); + let expected = Name::new("Big Mike"); - assert_eq!(parsed, expected); + assert_eq!(parsed, expected); + } } - { - let line = "name Big Mike"; - let parsed = parse_save_name(line).unwrap(); - let expected = Name::new("Big Mike"); + + #[test] + fn test_parse_uuid() { + let line = "uuid 1c16ab9a-5f79-4340-8469-4086f69c64f2"; + let parsed = parse_save_uuid(line).unwrap(); + let expected = Uuid::parse_str("1c16ab9a-5f79-4340-8469-4086f69c64f2").unwrap(); assert_eq!(parsed, expected); } } - - #[test] - fn test_parse_uuid() { - let line = "uuid 1c16ab9a-5f79-4340-8469-4086f69c64f2"; - let parsed = parse_save_uuid(line).unwrap(); - let expected = Uuid::parse_str("1c16ab9a-5f79-4340-8469-4086f69c64f2").unwrap(); - - assert_eq!(parsed, expected); - } } #[derive(Default)] @@ -199,7 +204,7 @@ enum SaveEntityLoaderError { #[error("Could not load asset: {0}")] Io(#[from] std::io::Error), #[error("Could not parse entity: {0}")] - Parse(#[from] SaveEntityParseError), + Parse(#[from] parse::SaveEntityParseError), } impl AssetLoader for SaveEntityLoader {