diff --git a/src/game.rs b/src/game.rs index 46072f4..61f9e71 100644 --- a/src/game.rs +++ b/src/game.rs @@ -15,13 +15,14 @@ //#![allow(clippy::missing_docs_in_private_items)] // A lot of our private items are simple digimon types, so they don't need documentation // Modules -mod util; - pub mod bytes; pub mod card; pub mod deck; +mod util; +pub mod validation; // Exports pub use bytes::Bytes; pub use card::{Digimon, Digivolve, Item, Table as CardTable}; pub use deck::{Deck, Table as DeckTable}; +pub use validation::{Validatable, Validation}; diff --git a/src/game/bytes.rs b/src/game/bytes.rs index db1e70c..a22b57c 100644 --- a/src/game/bytes.rs +++ b/src/game/bytes.rs @@ -1,11 +1,5 @@ //! Interface for converting various structures to and from bytes -// Modules -pub mod validation; - -// Exports -pub use validation::Validation; - // Std use std::{error::Error, fmt::Debug}; diff --git a/src/game/bytes/validation.rs b/src/game/bytes/validation.rs deleted file mode 100644 index 34d6c92..0000000 --- a/src/game/bytes/validation.rs +++ /dev/null @@ -1,83 +0,0 @@ -//! Error and warning validation for [`Bytes`](crate::Bytes) structures - -// Std -use std::borrow::Cow; - - -/// Validation for (`Bytes::validate`)[`crate::Bytes::validate`] -#[derive(Debug, PartialEq, Clone)] -pub struct Validation<'a> { - /// If the validation was successful. - /// - /// If this is `false`, it is strongly encouraged for `warnings` or - /// `errors` to have something to explain why it wasn't successful. - success: bool, - - /// All warnings emitted. - /// - /// Warnings must not be fatal. `self.to_bytes()` must succeed if only - /// warnings are emitted. - warnings: Vec>, - - /// All errors emitted. - /// - /// Errors are fatal by default, `self.to_bytes()` should fail if any errors - /// are emitted. - errors: Vec>, -} - -impl<'a> Default for Validation<'a> { - fn default() -> Self { - Self::new() - } -} - -// Constructors -impl<'a> Validation<'a> { - /// Create an empty successful validation, with no warnings or errors - #[must_use] - pub const fn new() -> Self { - Self { - success: true, - warnings: vec![], - errors: vec![], - } - } -} - -// Adders -impl<'a> Validation<'a> { - /// Adds a new warning to this validation. - pub fn add_warning(&mut self, warning: impl Into>) { - self.warnings.push(warning.into()); - } - - /// Adds a new error to this validation. - /// - /// This also turns the validation unsuccessful. - pub fn add_error(&mut self, error: impl Into>) { - self.errors.push(error.into()); - self.success = false; - } -} - -// Getters -impl<'a> Validation<'a> { - /// Returns if this validation was successful - #[must_use] - pub const fn successful(&self) -> bool { - self.success - } - - /// Returns all warnings - #[must_use] - pub fn warnings(&self) -> &[impl AsRef + 'a] { - &self.warnings - } - - /// Returns all errors - #[must_use] - pub fn errors(&self) -> &[impl AsRef + 'a] { - &self.errors - } -} diff --git a/src/game/validation.rs b/src/game/validation.rs new file mode 100644 index 0000000..3bedd87 --- /dev/null +++ b/src/game/validation.rs @@ -0,0 +1,49 @@ +//! Error and warning validation for structures + +/// Structures that are validatable to be written to bytes. +/// +/// This works in tandem with the [`Bytes`](crate::Bytes) interface to allow +/// applications which take user input to validate input before serializing it. +/// +/// Although this information exists by calling [`Bytes::to_bytes`](crate::Bytes::to_bytes), +/// this interface provides two main advantages: +/// +/// 1. It is faster than serializing the data, as it doesn't need to write the raw bytes and +/// can focus on simply parsing possible errors. +/// 2. It provides warnings alongside the errors. These are also provided via `log::warn`, but +/// these cannot be sent to the user easily. +pub trait Validatable { + /// Validation type + type Output: Validation; + + /// Validates this structure + fn validate(&self) -> Self::Output; +} + +/// A validation type. +/// +/// This is the output of structures which may be validated. +/// It is a trait to offer more flexibility to each structure to report +/// errors and warnings in it's preferred manner. +pub trait Validation: Clone { + /// Warnings type + type Warnings; + + /// Errors type + type Errors; + + /// If this validation was successful. + /// + /// A successful validation is one that, although may emit warnings, did not emit + /// any errors. Conversely, this also indicates that calling [`to_bytes`] will _not_ + /// produce a `Err` value. + fn successful(&self) -> bool { + self.errors().is_none() + } + + /// Returns any warnings + fn warnings(&self) -> Option; + + /// Returns any errors + fn errors(&self) -> Option; +} diff --git a/src/lib.rs b/src/lib.rs index 9a2ee59..dc2b03b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,5 +102,5 @@ pub mod game; pub mod io; // Exports -pub use game::{Bytes, CardTable, Deck, DeckTable, Digimon, Digivolve, Item}; +pub use game::{Bytes, CardTable, Deck, DeckTable, Digimon, Digivolve, Item, Validatable, Validation}; pub use io::GameFile;