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
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: std::fmt::Debug + std::fmt::Display + Sized + Clone + private::Sealed { type Point: std::fmt::Debug + Clone + PartialEq + Eq + std::hash::Hash + ToSgf; type Stone: std::fmt::Debug + Clone + PartialEq + Eq + std::hash::Hash + ToSgf; type Move: std::fmt::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 {} }