1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
use std::fmt::{Debug, Display};
use super::{PropertyType, ToSgf};
use crate::InvalidNodeError;
/// A type that can be used for properties in an [`SgfNode`](`crate::SgfNode`).
///
/// This trait is sealed and cannot be implemented for types outside of `sgf_parse`.
pub trait SgfProp: Debug + Display + Sized + Clone + Eq + private::Sealed {
type Point: Debug + Clone + PartialEq + Eq + std::hash::Hash + ToSgf;
type Stone: Debug + Clone + PartialEq + Eq + std::hash::Hash + ToSgf;
type Move: Debug + Clone + PartialEq + Eq + ToSgf;
/// Returns a new property parsed from the provided identifier and values
///
/// # Examples
/// ```
/// use sgf_parse::SgfProp;
/// use sgf_parse::go::Prop;
///
/// // Prop::B(Point{ x: 2, y: 3 }
/// let prop = Prop::new("B".to_string(), vec!["cd".to_string()]);
/// // Prop::AB(vec![Point{ x: 2, y: 3 }, Point { x: 3, y: 3 }])
/// let prop = Prop::new("AB".to_string(), vec!["cd".to_string(), "dd".to_string()]);
/// // Prop::Unknown("FOO", vec!["Text"])
/// let prop = Prop::new("FOO".to_string(), vec!["Text".to_string()]);
/// ```
fn new(identifier: String, values: Vec<String>) -> Self;
/// Returns a the identifier associated with the [`SgfProp`].
///
/// # Examples
/// ```
/// use sgf_parse::SgfProp;
/// use sgf_parse::go::Prop;
///
/// let prop = Prop::new("W".to_string(), vec!["de".to_string()]);
/// assert_eq!(prop.identifier(), "W");
/// let prop = Prop::new("FOO".to_string(), vec!["de".to_string()]);
/// assert_eq!(prop.identifier(), "FOO");
/// ```
fn identifier(&self) -> String;
/// Returns the [`PropertyType`] associated with the property.
///
/// # Examples
/// ```
/// use sgf_parse::{PropertyType, SgfProp};
/// use sgf_parse::go::Prop;
///
/// let prop = Prop::new("W".to_string(), vec!["de".to_string()]);
/// assert_eq!(prop.property_type(), Some(PropertyType::Move));
/// let prop = Prop::new("FOO".to_string(), vec!["de".to_string()]);
/// assert_eq!(prop.property_type(), None);
/// ```
fn property_type(&self) -> Option<PropertyType>;
/// Validates a set of properties.
///
/// # Errors
/// Returns an error if the collection of properties isn't valid.
fn validate_properties(properties: &[Self], is_root: bool) -> Result<(), InvalidNodeError>;
}
// Prevent users from implementing the SgfProp trait.
// Because `parse` has to return an enum, with the current design, implementing
// a new game outside the crate is a mess.
//
// If you'd like to implement this trait for a new game, PR's are very welcome!
mod private {
pub trait Sealed {}
impl Sealed for crate::go::Prop {}
impl Sealed for crate::unknown_game::Prop {}
impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {}
}