nyandere 0.1.2

i help with keeping track of purchases. meow
Documentation
//! Introduce a new actor.
//!
//! This is required for any actor
//! before it can be used.
//!
//! # Motivation
//!
//! While the explicit creation does create some typing churn,
//! it has 2 advantages:
//!
//! 1. It reduces the likelihood of typos causing damage.
//!    Money handling applications
//!    are definitely not ones
//!    where one wants to have some
//!    payment not included
//!    because the finger slipped one key.
//! 2. It allows post-reference.
//!    For example,
//!    [`Concept`] can store a default price
//!    to use when none is specified and
//!    a GTIN it is referred to by.
//!    This allows using the default price
//!    when just scanning a GTIN!
//!
//! # Structure
//!
//! Since there are 3 different actors with different arguments
//! that can be created,
//! they are split into 3 different commands.
//! This is especially ergonomic with the [`crate::cmd_args`] macro,
//! since that means no `create` needs to write its own [`Resolve`] impl.
//! They all can use themselves as argument type.
//!
//! # Caveats
//!
//! Creating another actor with the same name
//! (or other handle, e.g. GTIN)
//! replaces the previous actor with that name
//! while also replacing all references for future actions.
//! Previously done payments or deliveries are unaffected!

mod concept;
mod entity;
mod object;

pub use concept::CreateConcept;
pub use entity::CreateEntity;
pub use object::CreateObject;

#[cfg(test)]
mod tests {
    use crate::{Set, eval};

    #[test]
    fn inherit() {
        let rt = eval(
            "
            create entity A
            create entity B

            create concept E price=13.37€ gtin=10000000
            create object O parent=E
            create object T parent=E

            create entity C
            ",
        )
        .unwrap();

        // all entities there?
        assert_eq!(
            rt.entities.keys().map(AsRef::as_ref).collect::<Set<_>>(),
            ["A", "B", "C"].into_iter().collect(),
        );

        assert_eq!(
            rt.to_state()
                .objects
                .into_values()
                .map(|o| (o.name.unwrap(), o.parent.unwrap().name))
                .collect::<Set<_>>(),
            Set::from([("O".into(), "E".into()), ("T".into(), "E".into())])
        );
    }
}