Work on child conversions and error handling

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

View File

@ -5,27 +5,35 @@ use crate::{
use std::{collections::HashSet, time::Duration};
use uuid::Uuid;
#[derive(Clone, Debug, PartialEq)]
pub enum GameError {
InvalidGame,
RequiredPropertiesMissing,
InvalidGameNode(GameNodeError),
}
#[derive(Clone, Debug, PartialEq)]
pub enum MoveNodeError {
IncompatibleProperty,
IncompatibleProperty(parser::Property),
ConflictingProperty,
NotAMoveNode,
ChildError(Box<GameNodeError>),
}
#[derive(Clone, Debug, PartialEq)]
pub enum SetupNodeError {
IncompatibleProperty,
IncompatibleProperty(parser::Property),
ConflictingProperty,
ConflictingPosition,
}
#[derive(Clone, Debug, PartialEq)]
pub enum GameError {
InvalidGame,
RequiredPropertiesMissing,
NotASetupNode,
ChildError(Box<GameNodeError>),
}
#[derive(Clone, Debug, PartialEq)]
pub enum GameNodeError {
UnsupportedGameNode,
UnsupportedGameNode(MoveNodeError, SetupNodeError),
ConflictingProperty,
ConflictingPosition,
}
#[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)
}
}
@ -252,10 +268,16 @@ impl Node for GameNode {
impl TryFrom<&parser::Node> for GameNode {
type Error = GameNodeError;
fn try_from(n: &parser::Node) -> Result<Self, Self::Error> {
MoveNode::try_from(n)
.map(GameNode::MoveNode)
.or_else(|_| SetupNode::try_from(n).map(GameNode::SetupNode))
.map_err(|_| Self::Error::UnsupportedGameNode)
let move_node = MoveNode::try_from(n);
let setup_node = SetupNode::try_from(n);
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;
fn try_from(n: &parser::Node) -> Result<Self, Self::Error> {
match n.mv() {
let mut s = match n.mv() {
Some((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 }) => {
s.unknown_props.push((ident.clone(), value.clone()));
}
_ => return Err(Self::Error::IncompatibleProperty),
_ => return Err(Self::Error::IncompatibleProperty(prop.clone())),
}
}
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> {
match n.setup() {
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![],
};
assert_eq!(
assert_matches!(
MoveNode::try_from(&n),
Err(MoveNodeError::IncompatibleProperty)
Err(MoveNodeError::IncompatibleProperty(_))
);
}
}
@ -603,9 +635,9 @@ mod path_test {
#[cfg(test)]
mod file_test {
use crate::Win;
use super::*;
use crate::Win;
use cool_asserts::assert_matches;
use parser::parse_collection;
use std::{fs::File, io::Read};
@ -693,27 +725,26 @@ mod file_test {
for i in 0..16 {
assert_eq!(node.properties[i], expected_properties[i]);
}
*/
let node = node.next().unwrap();
let expected_properties = vec![
Property {
ident: "B".to_owned(),
values: vec!["pp".to_owned()],
},
Property {
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 = game.children();
let node = children.first().unwrap();
assert_matches!(node, GameNode::MoveNode(node) => {
assert_eq!(node.color, Color::Black);
assert_eq!(node.mv, Move::Move("pp".to_owned()));
assert_eq!(node.time_left, Some(Duration::from_secs(1795)));
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())
)});
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 expected_properties = vec![
Property {

View File

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