Work on child conversions and error handling

This commit is contained in:
Savanni D'Gerinel 2023-09-19 18:26:52 -04:00
parent 99bb36dbcd
commit 70191d3687
2 changed files with 73 additions and 42 deletions

View File

@ -5,27 +5,35 @@ use crate::{
use std::{collections::HashSet, time::Duration}; use std::{collections::HashSet, time::Duration};
use uuid::Uuid; use uuid::Uuid;
#[derive(Clone, Debug, PartialEq)]
pub enum GameError {
InvalidGame,
RequiredPropertiesMissing,
InvalidGameNode(GameNodeError),
}
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum MoveNodeError { pub enum MoveNodeError {
IncompatibleProperty, IncompatibleProperty(parser::Property),
ConflictingProperty, ConflictingProperty,
NotAMoveNode,
ChildError(Box<GameNodeError>),
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum SetupNodeError { pub enum SetupNodeError {
IncompatibleProperty, IncompatibleProperty(parser::Property),
ConflictingProperty,
ConflictingPosition, ConflictingPosition,
} NotASetupNode,
ChildError(Box<GameNodeError>),
#[derive(Clone, Debug, PartialEq)]
pub enum GameError {
InvalidGame,
RequiredPropertiesMissing,
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum GameNodeError { pub enum GameNodeError {
UnsupportedGameNode, UnsupportedGameNode(MoveNodeError, SetupNodeError),
ConflictingProperty,
ConflictingPosition,
} }
#[derive(Clone, Debug, PartialEq, Default)] #[derive(Clone, Debug, PartialEq, Default)]
@ -188,6 +196,14 @@ impl TryFrom<&parser::Tree> for Game {
} }
} }
s.children = tree
.root
.next
.iter()
.map(|node| GameNode::try_from(node))
.collect::<Result<Vec<GameNode>, GameNodeError>>()
.map_err(GameError::InvalidGameNode)?;
Ok(s) Ok(s)
} }
} }
@ -252,10 +268,16 @@ impl Node for GameNode {
impl TryFrom<&parser::Node> for GameNode { impl TryFrom<&parser::Node> for GameNode {
type Error = GameNodeError; type Error = GameNodeError;
fn try_from(n: &parser::Node) -> Result<Self, Self::Error> { fn try_from(n: &parser::Node) -> Result<Self, Self::Error> {
MoveNode::try_from(n) let move_node = MoveNode::try_from(n);
.map(GameNode::MoveNode) let setup_node = SetupNode::try_from(n);
.or_else(|_| SetupNode::try_from(n).map(GameNode::SetupNode))
.map_err(|_| Self::Error::UnsupportedGameNode) match (move_node, setup_node) {
(Ok(node), _) => Ok(Self::MoveNode(node)),
(Err(_), Ok(node)) => Ok(Self::SetupNode(node)),
(Err(move_err), Err(setup_err)) => {
Err(Self::Error::UnsupportedGameNode(move_err, setup_err))
}
}
} }
} }
@ -311,7 +333,7 @@ impl TryFrom<&parser::Node> for MoveNode {
type Error = MoveNodeError; type Error = MoveNodeError;
fn try_from(n: &parser::Node) -> Result<Self, Self::Error> { fn try_from(n: &parser::Node) -> Result<Self, Self::Error> {
match n.mv() { let mut s = match n.mv() {
Some((color, mv)) => { Some((color, mv)) => {
let mut s = Self::new(color, mv); let mut s = Self::new(color, mv);
@ -352,14 +374,24 @@ impl TryFrom<&parser::Node> for MoveNode {
parser::Property::Unknown(UnknownProperty { ident, value }) => { parser::Property::Unknown(UnknownProperty { ident, value }) => {
s.unknown_props.push((ident.clone(), value.clone())); s.unknown_props.push((ident.clone(), value.clone()));
} }
_ => return Err(Self::Error::IncompatibleProperty), _ => return Err(Self::Error::IncompatibleProperty(prop.clone())),
} }
} }
Ok(s) Ok(s)
} }
None => Err(MoveNodeError::IncompatibleProperty), None => Err(Self::Error::NotAMoveNode),
} }?;
s.children = n
.next
.iter()
.map(|node| {
GameNode::try_from(node).map_err(|err| Self::Error::ChildError(Box::new(err)))
})
.collect::<Result<Vec<GameNode>, MoveNodeError>>()?;
Ok(s)
} }
} }
@ -409,7 +441,7 @@ impl TryFrom<&parser::Node> for SetupNode {
fn try_from(n: &parser::Node) -> Result<Self, Self::Error> { fn try_from(n: &parser::Node) -> Result<Self, Self::Error> {
match n.setup() { match n.setup() {
Some(elements) => Self::new(elements), Some(elements) => Self::new(elements),
None => Err(Self::Error::IncompatibleProperty), None => Err(Self::Error::NotASetupNode),
} }
} }
} }
@ -548,9 +580,9 @@ mod move_node_tests {
], ],
next: vec![], next: vec![],
}; };
assert_eq!( assert_matches!(
MoveNode::try_from(&n), MoveNode::try_from(&n),
Err(MoveNodeError::IncompatibleProperty) Err(MoveNodeError::IncompatibleProperty(_))
); );
} }
} }
@ -603,9 +635,9 @@ mod path_test {
#[cfg(test)] #[cfg(test)]
mod file_test { mod file_test {
use crate::Win;
use super::*; use super::*;
use crate::Win;
use cool_asserts::assert_matches;
use parser::parse_collection; use parser::parse_collection;
use std::{fs::File, io::Read}; use std::{fs::File, io::Read};
@ -693,27 +725,26 @@ mod file_test {
for i in 0..16 { for i in 0..16 {
assert_eq!(node.properties[i], expected_properties[i]); assert_eq!(node.properties[i], expected_properties[i]);
} }
*/
let node = node.next().unwrap(); let children = game.children();
let expected_properties = vec![ let node = children.first().unwrap();
Property { assert_matches!(node, GameNode::MoveNode(node) => {
ident: "B".to_owned(), assert_eq!(node.color, Color::Black);
values: vec!["pp".to_owned()], assert_eq!(node.mv, Move::Move("pp".to_owned()));
}, assert_eq!(node.time_left, Some(Duration::from_secs(1795)));
Property { assert_eq!(node.comments, Some("Geckoz [?]: Good game\nsavanni [23k?]: There we go! This UI is... tough.\nsavanni [23k?]: Have fun! Talk to you at the end.\nGeckoz [?]: Yeah, OGS is much better; I'm a UX professional\n".to_owned())
ident: "BL".to_owned(), )});
values: vec!["1795.449".to_owned()],
},
Property {
ident: "C".to_owned(),
values: vec!["Geckoz [?]: Good game\nsavanni [23k?]: There we go! This UI is... tough.\nsavanni [23k?]: Have fun! Talk to you at the end.\nGeckoz [?]: Yeah, OGS is much better; I'm a UX professional\n".to_owned()],
}
];
for i in 0..3 {
assert_eq!(node.properties[i], expected_properties[i]);
}
let children = node.children();
let node = children.first().unwrap();
assert_matches!(node, GameNode::MoveNode(node) => {
assert_eq!(node.color, Color::White);
assert_eq!(node.mv, Move::Move("dp".to_owned()));
assert_eq!(node.time_left, Some(Duration::from_secs(1765)));
assert_eq!(node.comments, None);
});
/*
let node = node.next().unwrap(); let node = node.next().unwrap();
let expected_properties = vec![ let expected_properties = vec![
Property { Property {

View File

@ -300,7 +300,7 @@ impl Node {
.collect::<Vec<SetupInstr>>(), .collect::<Vec<SetupInstr>>(),
); );
} }
_ => unimplemented!(), _ => return None,
} }
} }
if setup.len() > 0 { if setup.len() > 0 {