qa 0.1.1

Requirements traceability for safety-critical Rust software
Documentation
use crate::RequirementType::*;

crate::requirements! {
    pub REQ_DEFINE_AS_CODE: Functional {
        description: "Requirements must be definable as static items via declarative macro",
    }

    pub REQ_NO_STD: NonFunctional {
        description: "Core types and macros must work in no_std environments",
    }
}

use core::fmt;
use linkme::distributed_slice;

/// Classification of a requirement.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RequirementType {
    Functional,
    NonFunctional,
    Performance,
    Safety,
    Security,
    Interface,
    Custom(&'static str),
}

impl fmt::Display for RequirementType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Functional => f.write_str("Functional"),
            Self::NonFunctional => f.write_str("NonFunctional"),
            Self::Performance => f.write_str("Performance"),
            Self::Safety => f.write_str("Safety"),
            Self::Security => f.write_str("Security"),
            Self::Interface => f.write_str("Interface"),
            Self::Custom(s) => f.write_str(s),
        }
    }
}

/// A traceable requirement defined in source code.
///
/// Created via [`requirement!`](crate::requirement!) or
/// [`requirements!`](crate::requirements!). Registered automatically
/// with a `linkme` distributed slice for collection into a traceability matrix.
#[derive(Debug)]
pub struct Requirement {
    pub id: &'static str,
    pub kind: RequirementType,
    pub description: &'static str,
    pub module: &'static str,
    pub file: &'static str,
    pub line: u32,
    pub metadata: &'static [(&'static str, &'static str)],
}

impl Requirement {
    /// Look up a metadata value by key.
    pub fn get(&self, key: &str) -> Option<&'static str> {
        self.metadata
            .iter()
            .find(|(k, _)| *k == key)
            .map(|(_, v)| *v)
    }
}

#[distributed_slice]
pub static REQUIREMENTS: [Requirement];