|
|
|
@ -21,15 +21,15 @@ struct SaveEntity {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl SaveEntity {
|
|
|
|
impl SaveEntity {
|
|
|
|
fn parse(s: &str) -> Result<SaveEntity, SaveEntityParseError> {
|
|
|
|
fn parse(s: &str) -> Result<SaveEntity, parse::SaveEntityParseError> {
|
|
|
|
let lines = s.split('\n');
|
|
|
|
let lines = s.split('\n');
|
|
|
|
let mut entity = SaveEntity { ..default() };
|
|
|
|
let mut entity = SaveEntity { ..default() };
|
|
|
|
lines.into_iter().for_each(|line| {
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
entity.uuid = Some(uuid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
@ -37,158 +37,163 @@ impl SaveEntity {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Error, Debug)]
|
|
|
|
mod parse {
|
|
|
|
enum SaveEntityParseError {
|
|
|
|
use super::*;
|
|
|
|
#[error("Failed to parse Uuid: {0}")]
|
|
|
|
|
|
|
|
Uuid(#[from] uuid::Error),
|
|
|
|
#[derive(Error, Debug)]
|
|
|
|
#[error("Failed to parse name")]
|
|
|
|
pub(crate) enum SaveEntityParseError {
|
|
|
|
Name,
|
|
|
|
#[error("Failed to parse Uuid: {0}")]
|
|
|
|
#[error("Failed to parse Transform")]
|
|
|
|
Uuid(#[from] uuid::Error),
|
|
|
|
Transform,
|
|
|
|
#[error("Failed to parse name")]
|
|
|
|
#[error("Failed to parse Entity")]
|
|
|
|
Name,
|
|
|
|
Nom(nom::Err<nom::error::Error<Box<str>>>),
|
|
|
|
#[error("Failed to parse Transform")]
|
|
|
|
}
|
|
|
|
Transform,
|
|
|
|
|
|
|
|
#[error("Failed to parse Entity")]
|
|
|
|
|
|
|
|
Nom(nom::Err<nom::error::Error<Box<str>>>),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Convert Nom error to parse error
|
|
|
|
// Convert Nom error to parse error
|
|
|
|
// https://stackoverflow.com/a/77974858/3096574
|
|
|
|
// https://stackoverflow.com/a/77974858/3096574
|
|
|
|
impl From<nom::Err<nom::error::Error<&str>>> for SaveEntityParseError {
|
|
|
|
impl From<nom::Err<nom::error::Error<&str>>> for SaveEntityParseError {
|
|
|
|
fn from(err: nom::Err<nom::error::Error<&str>>) -> Self {
|
|
|
|
fn from(err: nom::Err<nom::error::Error<&str>>) -> Self {
|
|
|
|
SaveEntityParseError::Nom(err.map_input(|input| input.into()))
|
|
|
|
SaveEntityParseError::Nom(err.map_input(|input| input.into()))
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_thing<'a>(s: &'a str, l: &'a str) -> IResult<&'a str, &'a str> {
|
|
|
|
fn parse_thing<'a>(s: &'a str, l: &'a str) -> IResult<&'a str, &'a str> {
|
|
|
|
tag(l)(s)
|
|
|
|
tag(l)(s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_xyz<'a>(i: &'a str) -> IResult<&'a str, (f32, f32, f32)> {
|
|
|
|
fn parse_xyz<'a>(i: &'a str) -> IResult<&'a str, (f32, f32, f32)> {
|
|
|
|
tuple((float, take(1usize), float, take(1usize), float))(i)
|
|
|
|
tuple((float, take(1usize), float, take(1usize), float))(i)
|
|
|
|
.map(|(s, (x, _, y, _, z))| (s, (x, y, z)))
|
|
|
|
.map(|(s, (x, _, y, _, z))| (s, (x, y, z)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_wxyz<'a>(i: &'a str) -> IResult<&'a str, (f32, f32, f32, f32)> {
|
|
|
|
fn parse_wxyz<'a>(i: &'a str) -> IResult<&'a str, (f32, f32, f32, f32)> {
|
|
|
|
tuple((
|
|
|
|
tuple((
|
|
|
|
float,
|
|
|
|
float,
|
|
|
|
take(1usize),
|
|
|
|
take(1usize),
|
|
|
|
float,
|
|
|
|
float,
|
|
|
|
take(1usize),
|
|
|
|
take(1usize),
|
|
|
|
float,
|
|
|
|
float,
|
|
|
|
take(1usize),
|
|
|
|
take(1usize),
|
|
|
|
float,
|
|
|
|
float,
|
|
|
|
))(i)
|
|
|
|
))(i)
|
|
|
|
.map(|(s, (w, _, x, _, y, _, z))| (s, (w, x, y, z)))
|
|
|
|
.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 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 };
|
|
|
|
/// 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);
|
|
|
|
/// assert_eq!(parsed, expected);
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
///
|
|
|
|
fn parse_save_transform(line: &str) -> Result<Transform, SaveEntityParseError> {
|
|
|
|
pub(crate) fn parse_save_transform(line: &str) -> Result<Transform, SaveEntityParseError> {
|
|
|
|
let (rem, _) = tag("transform")(line)?;
|
|
|
|
let (rem, _) = tag("transform")(line)?;
|
|
|
|
|
|
|
|
|
|
|
|
let mut transform = Transform::default();
|
|
|
|
let mut transform = Transform::default();
|
|
|
|
|
|
|
|
|
|
|
|
let mut curr = rem.trim_start();
|
|
|
|
let mut curr = rem.trim_start();
|
|
|
|
for _ in 0..3 {
|
|
|
|
for _ in 0..3 {
|
|
|
|
if let Ok((input, _)) = parse_thing(curr, "translation") {
|
|
|
|
if let Ok((input, _)) = parse_thing(curr, "translation") {
|
|
|
|
let (rem, (x, y, z)) = parse_xyz(input.trim_start())?;
|
|
|
|
let (rem, (x, y, z)) = parse_xyz(input.trim_start())?;
|
|
|
|
transform.translation = Vec3::new(x, y, z);
|
|
|
|
transform.translation = Vec3::new(x, y, z);
|
|
|
|
curr = rem.trim_start();
|
|
|
|
curr = rem.trim_start();
|
|
|
|
} else if let Ok((input, _)) = parse_thing(curr.trim_start(), "rotation") {
|
|
|
|
} else if let Ok((input, _)) = parse_thing(curr.trim_start(), "rotation") {
|
|
|
|
let (rem, (x, y, z, w)) = parse_wxyz(input.trim_start())?;
|
|
|
|
let (rem, (x, y, z, w)) = parse_wxyz(input.trim_start())?;
|
|
|
|
transform.rotation = Quat::from_xyzw(x, y, z, w);
|
|
|
|
transform.rotation = Quat::from_xyzw(x, y, z, w);
|
|
|
|
curr = rem.trim_start();
|
|
|
|
curr = rem.trim_start();
|
|
|
|
} else if let Ok((input, _)) = parse_thing(curr.trim_start(), "scale") {
|
|
|
|
} else if let Ok((input, _)) = parse_thing(curr.trim_start(), "scale") {
|
|
|
|
let (rem, (x, y, z)) = parse_xyz(input.trim_start())?;
|
|
|
|
let (rem, (x, y, z)) = parse_xyz(input.trim_start())?;
|
|
|
|
transform.scale = Vec3::new(x, y, z);
|
|
|
|
transform.scale = Vec3::new(x, y, z);
|
|
|
|
curr = rem.trim_start();
|
|
|
|
curr = rem.trim_start();
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return Err(SaveEntityParseError::Transform);
|
|
|
|
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<Name, SaveEntityParseError> {
|
|
|
|
|
|
|
|
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 parsed = parse_save_uuid("uuid 339dd18f-761a-4997-b515-ef57f4dc2447").unwrap();
|
|
|
|
/// let expected = Name::new("asdf");
|
|
|
|
/// let expected = Uuid::parse_str("339dd18f-761a-4997-b515-ef57f4dc2447").unwrap();
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// assert_eq!(parsed, expected);
|
|
|
|
/// assert_eq!(parsed, expected);
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
///
|
|
|
|
fn parse_save_name(line: &str) -> Result<Name, SaveEntityParseError> {
|
|
|
|
pub(crate) fn parse_save_uuid(line: &str) -> Result<Uuid, SaveEntityParseError> {
|
|
|
|
let (remainder, _) = tag("name")(line)?;
|
|
|
|
let (remainder, _) = tag("uuid")(line)?;
|
|
|
|
let n = remainder.trim().to_string();
|
|
|
|
let uuid = Uuid::try_parse(remainder.trim())?;
|
|
|
|
if n.len() == 0 {
|
|
|
|
Ok(uuid)
|
|
|
|
Err(SaveEntityParseError::Name)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
let name = Name::new(n);
|
|
|
|
|
|
|
|
Ok(name)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
mod test {
|
|
|
|
/// ```
|
|
|
|
use super::*;
|
|
|
|
/// 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<Uuid, SaveEntityParseError> {
|
|
|
|
|
|
|
|
let (remainder, _) = tag("uuid")(line)?;
|
|
|
|
|
|
|
|
let uuid = Uuid::try_parse(remainder.trim())?;
|
|
|
|
|
|
|
|
Ok(uuid)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mod test {
|
|
|
|
#[test]
|
|
|
|
use super::*;
|
|
|
|
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]
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
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);
|
|
|
|
#[test]
|
|
|
|
}
|
|
|
|
fn test_parse_name() {
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let line = "name Van";
|
|
|
|
|
|
|
|
let parsed = parse_save_name(line).unwrap();
|
|
|
|
|
|
|
|
let expected = Name::new("Van");
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
fn test_parse_name() {
|
|
|
|
}
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let line = "name Van";
|
|
|
|
let line = "name Big Mike";
|
|
|
|
let parsed = parse_save_name(line).unwrap();
|
|
|
|
let parsed = parse_save_name(line).unwrap();
|
|
|
|
let expected = Name::new("Van");
|
|
|
|
let expected = Name::new("Big Mike");
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
|
|
|
|
let line = "name Big Mike";
|
|
|
|
#[test]
|
|
|
|
let parsed = parse_save_name(line).unwrap();
|
|
|
|
fn test_parse_uuid() {
|
|
|
|
let expected = Name::new("Big Mike");
|
|
|
|
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);
|
|
|
|
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)]
|
|
|
|
#[derive(Default)]
|
|
|
|
@ -199,7 +204,7 @@ enum SaveEntityLoaderError {
|
|
|
|
#[error("Could not load asset: {0}")]
|
|
|
|
#[error("Could not load asset: {0}")]
|
|
|
|
Io(#[from] std::io::Error),
|
|
|
|
Io(#[from] std::io::Error),
|
|
|
|
#[error("Could not parse entity: {0}")]
|
|
|
|
#[error("Could not parse entity: {0}")]
|
|
|
|
Parse(#[from] SaveEntityParseError),
|
|
|
|
Parse(#[from] parse::SaveEntityParseError),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl AssetLoader for SaveEntityLoader {
|
|
|
|
impl AssetLoader for SaveEntityLoader {
|
|
|
|
|