#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum Kind {
Manifest,
DerivedFrom,
Labels,
Counters,
Binding,
TagEntry,
CategoryEntry,
Product,
FeatureGroup,
Feature,
Requirement,
Statement,
Criterion,
RootComponent,
Component,
Constraint,
ConstraintBinding,
QualityAttribute,
QualityTarget,
Band,
Section,
Decision,
State,
Driver,
Option,
Assessment,
Consequence,
Subject,
FormerLabel,
ByName,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Scalar {
Key,
Ref(Target),
Label,
Slug,
Tag,
Category,
Digest,
Integer,
Enum(&'static [&'static str]),
Identifier,
Text,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Target {
Node,
Component,
Product,
Decision,
NodeOrDecision,
Option,
Driver,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Shape {
One(Item),
List(Item),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Item {
Scalar(Scalar),
Record(Kind),
NodeRef,
}
impl Shape {
#[must_use]
pub const fn item(self) -> Item {
match self {
Self::One(item) | Self::List(item) => item,
}
}
}
impl Item {
#[must_use]
pub const fn target(self) -> Option<Target> {
match self {
Self::Scalar(Scalar::Ref(target)) => Some(target),
Self::NodeRef => Some(Target::Node),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Order {
Authored,
ByKey,
ByRoleThenTarget,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Supply {
MintKey,
SlugFromPath,
SlugFromName,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Field {
pub name: &'static str,
pub required: bool,
pub shape: Shape,
pub order: Order,
pub supply: Option<Supply>,
}
pub use super::field;
mod tables;
use crate::kind::NodeKind;
impl Kind {
pub const ALL: [Self; 30] = [
Self::Manifest,
Self::DerivedFrom,
Self::Labels,
Self::Counters,
Self::Binding,
Self::TagEntry,
Self::CategoryEntry,
Self::Product,
Self::FeatureGroup,
Self::Feature,
Self::Requirement,
Self::Statement,
Self::Criterion,
Self::RootComponent,
Self::Component,
Self::Constraint,
Self::ConstraintBinding,
Self::QualityAttribute,
Self::QualityTarget,
Self::Band,
Self::Section,
Self::Decision,
Self::State,
Self::Driver,
Self::Option,
Self::Assessment,
Self::Consequence,
Self::Subject,
Self::FormerLabel,
Self::ByName,
];
#[must_use]
pub const fn fields(self) -> &'static [Field] {
tables::fields(self)
}
#[must_use]
pub fn field(self, name: &str) -> Option<(usize, &'static Field)> {
self.fields()
.iter()
.enumerate()
.find(|(_, field)| field.name == name)
}
#[must_use]
pub const fn is_keyed(self) -> bool {
let fields = self.fields();
let mut index = 0;
while index < fields.len() {
if matches!(fields[index].supply, Some(Supply::MintKey)) {
return true;
}
index += 1;
}
false
}
#[must_use]
pub const fn hosts_conflicts(self) -> bool {
self.is_keyed() || matches!(self, Self::Manifest | Self::Labels)
}
#[must_use]
pub const fn node_kind(self) -> Option<NodeKind> {
Some(match self {
Self::Product => NodeKind::Product,
Self::FeatureGroup => NodeKind::FeatureGroup,
Self::Feature => NodeKind::Feature,
Self::Requirement => NodeKind::Requirement,
Self::Criterion => NodeKind::Criterion,
Self::RootComponent | Self::Component => NodeKind::Component,
Self::Constraint => NodeKind::Constraint,
Self::QualityAttribute => NodeKind::QualityAttribute,
Self::Section => NodeKind::Section,
_ => return None,
})
}
}