cartulary 0.3.0-alpha.1

The knowledge layer of your project — decisions, issues, docs, all in one place.
Documentation
//! A single load-time failure reported by an [`EntryDefectScanner`].
//!
//! Carries enough to point a human at the broken source (`location`),
//! tell them whether it comes from the writable home or a union source
//! (`origin`), and explain what went wrong (`defect`). Kind-neutral:
//! attribution to issues vs decision-records is contextual (the caller
//! knows which scanner produced the entry).

use crate::domain::model::entry_locator::EntryLocator;
use crate::domain::model::entry_origin::EntryOrigin;
use crate::domain::model::load_defect::LoadDefect;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MalformedEntry {
    pub location: EntryLocator,
    pub origin: EntryOrigin,
    pub defect: LoadDefect,
}

#[cfg(test)]
pub mod strategy {
    use super::*;
    use proptest::prelude::*;

    pub fn arb_malformed_entry() -> impl Strategy<Value = MalformedEntry> {
        (
            "[a-z0-9/_.-]{1,40}".prop_map(EntryLocator::new),
            prop_oneof![
                Just(EntryOrigin::Local),
                "[a-z0-9/_.-]{1,40}".prop_map(|name| EntryOrigin::Union { name }),
            ],
            crate::domain::model::load_defect::strategy::arb_load_defect(),
        )
            .prop_map(|(location, origin, defect)| MalformedEntry {
                location,
                origin,
                defect,
            })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn equality_is_field_by_field() {
        let a = MalformedEntry {
            location: EntryLocator::new("docs/adr/0001.md"),
            origin: EntryOrigin::Local,
            defect: LoadDefect::MissingId,
        };
        let b = a.clone();
        assert_eq!(a, b);
    }

    #[test]
    fn different_origin_breaks_equality() {
        let base = MalformedEntry {
            location: EntryLocator::new("docs/adr/0001.md"),
            origin: EntryOrigin::Local,
            defect: LoadDefect::MissingId,
        };
        let other = MalformedEntry {
            origin: EntryOrigin::Union {
                name: "../shared/adr".into(),
            },
            ..base.clone()
        };
        assert_ne!(base, other);
    }
}