#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FieldName {
Id,
Type,
Name,
Description,
Refines,
DerivesFrom,
Satisfies,
IsRefinedBy,
Derives,
IsSatisfiedBy,
DependsOn,
IsRequiredBy,
Specification,
Platform,
JustifiedBy,
Status,
Deciders,
Justifies,
Supersedes,
SupersededBy,
}
impl FieldName {
pub const fn all() -> &'static [FieldName] {
&[
Self::Id,
Self::Type,
Self::Name,
Self::Description,
Self::Refines,
Self::DerivesFrom,
Self::Satisfies,
Self::IsRefinedBy,
Self::Derives,
Self::IsSatisfiedBy,
Self::DependsOn,
Self::IsRequiredBy,
Self::Specification,
Self::Platform,
Self::JustifiedBy,
Self::Status,
Self::Deciders,
Self::Justifies,
Self::Supersedes,
Self::SupersededBy,
]
}
pub const fn as_str(&self) -> &'static str {
match self {
Self::Id => "id",
Self::Type => "type",
Self::Name => "name",
Self::Description => "description",
Self::Refines => "refines",
Self::DerivesFrom => "derives_from",
Self::Satisfies => "satisfies",
Self::IsRefinedBy => "is_refined_by",
Self::Derives => "derives",
Self::IsSatisfiedBy => "is_satisfied_by",
Self::DependsOn => "depends_on",
Self::IsRequiredBy => "is_required_by",
Self::Specification => "specification",
Self::Platform => "platform",
Self::JustifiedBy => "justified_by",
Self::Status => "status",
Self::Deciders => "deciders",
Self::Justifies => "justifies",
Self::Supersedes => "supersedes",
Self::SupersededBy => "superseded_by",
}
}
pub const fn display_name(&self) -> &'static str {
match self {
Self::Id => "ID",
Self::Type => "Type",
Self::Name => "Name",
Self::Description => "Description",
Self::Refines => "Refines",
Self::DerivesFrom => "Derives from",
Self::Satisfies => "Satisfies",
Self::IsRefinedBy => "Is refined by",
Self::Derives => "Derives",
Self::IsSatisfiedBy => "Is satisfied by",
Self::DependsOn => "Depends on",
Self::IsRequiredBy => "Is required by",
Self::Specification => "Specification",
Self::Platform => "Platform",
Self::JustifiedBy => "Justified by",
Self::Status => "Status",
Self::Deciders => "Deciders",
Self::Justifies => "Justifies",
Self::Supersedes => "Supersedes",
Self::SupersededBy => "Superseded by",
}
}
pub const fn is_upstream(&self) -> bool {
matches!(
self,
Self::Refines | Self::DerivesFrom | Self::Satisfies | Self::Justifies
)
}
pub const fn is_downstream(&self) -> bool {
matches!(
self,
Self::IsRefinedBy | Self::Derives | Self::IsSatisfiedBy | Self::JustifiedBy
)
}
pub const fn is_peer(&self) -> bool {
matches!(
self,
Self::DependsOn | Self::IsRequiredBy | Self::Supersedes | Self::SupersededBy
)
}
pub const fn is_traceability(&self) -> bool {
self.is_upstream() || self.is_downstream() || self.is_peer()
}
}
impl std::fmt::Display for FieldName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_field_name_as_str() {
assert_eq!(FieldName::Id.as_str(), "id");
assert_eq!(FieldName::DerivesFrom.as_str(), "derives_from");
assert_eq!(FieldName::Specification.as_str(), "specification");
}
#[test]
fn test_field_name_is_upstream() {
assert!(FieldName::Refines.is_upstream());
assert!(FieldName::DerivesFrom.is_upstream());
assert!(FieldName::Satisfies.is_upstream());
assert!(!FieldName::IsRefinedBy.is_upstream());
assert!(!FieldName::Specification.is_upstream());
}
#[test]
fn test_field_name_is_downstream() {
assert!(FieldName::IsRefinedBy.is_downstream());
assert!(FieldName::Derives.is_downstream());
assert!(FieldName::IsSatisfiedBy.is_downstream());
assert!(!FieldName::Refines.is_downstream());
}
#[test]
fn test_field_name_all() {
let all = FieldName::all();
assert!(all.contains(&FieldName::Id));
assert!(all.contains(&FieldName::Refines));
assert!(all.contains(&FieldName::Specification));
assert!(all.contains(&FieldName::Status));
assert!(all.contains(&FieldName::Justifies));
assert_eq!(all.len(), 20);
}
#[test]
fn test_field_name_display() {
assert_eq!(format!("{}", FieldName::DerivesFrom), "derives_from");
}
}