der_die_das 0.5.0

der_die_das: Learn german genders like a true geek.
Documentation
use std::fmt::Display;

use miette::Result;
use serde::{Deserialize, Serialize};

use crate::id::ID;

#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct Noun {
    pub articles: Vec<Article>,
    pub word: String,
    pub meaning: String,
    pub group: String,
}

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct SavedNoun {
    pub id: ID,
    pub at: time::OffsetDateTime,
    pub noun: Noun,
}
impl From<Noun> for SavedNoun {
    fn from(noun: Noun) -> Self {
        SavedNoun {
            id: ID::new(),
            at: time::OffsetDateTime::now_utc(),
            noun,
        }
    }
}

#[derive(
    Debug, Clone, Copy, clap::ValueEnum, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize,
)]
#[serde(rename_all = "lowercase")]
pub enum Article {
    Der,
    Die,
    Das,
}

impl Display for Article {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{}",
            match self {
                Article::Der => "der",
                Article::Die => "die",
                Article::Das => "das",
            }
        )
    }
}

pub trait Repo: Clone + Send + Sync + std::fmt::Debug {
    /// Saves one noun.
    ///
    /// # Errors
    ///
    /// This function will return an error if the noun with the same ID already
    /// exist or there is an IO failure.
    fn save_noun(self, noun: SavedNoun) -> Result<()>;

    /// Returns all the nouns
    ///
    /// # Errors
    ///
    /// This function will return an error if there is an IO Failure.
    fn all_nouns(self) -> Result<Vec<SavedNoun>>;

    /// Find noun by specific ID
    ///
    /// # Errors
    ///
    /// This function will return an error if a noun by that ID does not exist
    /// or there is an IO failure.
    fn find_noun_by_id(self, id: ID) -> Result<SavedNoun>;

    /// Delete the noun by its ID
    ///
    /// # Errors
    ///
    /// This function will return an error if a noun by that ID does not exist
    /// or there is an IO failure.
    fn delete_noun_by_id(self, id: ID) -> Result<()>;

    /// Edit noun
    ///
    /// # Errors
    ///
    /// This function will return an error if a noun by that ID does not exist
    /// or there is an IO failure.
    fn edit_noun_by_id(
        self,
        id: ID,
        article: Option<Vec<Article>>,
        word: Option<String>,
        meaning: Option<String>,
        group: Option<String>,
    ) -> Result<()>;
}