use super::type_contract::slot_in;
use crate::identity::{GeneratedUnit, Identity, OwnerFact, Profile};
use core::marker::PhantomData;
#[path = "type_guard.rs"]
mod guard;
pub trait Kind: 'static {
const NAME: &'static str;
type Content: CanonicalContent;
type Role: Role;
type Question: Question;
}
pub trait CanonicalContent: Clone + Eq + core::fmt::Debug {
fn encode_content_into(&self, into: &mut Vec<u8>);
#[must_use]
fn canonical_content_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
self.encode_content_into(&mut bytes);
bytes
}
}
pub trait Role: Copy + Eq + core::fmt::Debug + 'static {
const ALL: &'static [Self];
#[must_use]
fn name(self) -> &'static str;
#[must_use]
fn destination(self) -> Destination;
#[must_use]
fn slot(self) -> u16 {
slot_in(Self::ALL, self)
}
}
pub trait Question: Copy + Eq + core::fmt::Debug + 'static {
const ALL: &'static [Self];
type Answer: Answer<Question = Self>;
#[must_use]
fn name(self) -> &'static str;
#[must_use]
fn slot(self) -> u16 {
slot_in(Self::ALL, self)
}
}
pub trait Answer: Clone + Eq + core::fmt::Debug {
type Question: Question;
#[must_use]
fn question(&self) -> Self::Question;
fn encode_into(&self, into: &mut Vec<u8>);
#[must_use]
fn human(&self) -> String;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum NoQuestions {}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SoleRole {
Sole,
}
crate::roster! {
pub enum Destination {
DeclarationSite = "declaration-site",
TestCarrier = "test-carrier",
BenchCarrier = "bench-carrier",
PublicationArtifact = "publication-artifact",
}
}
#[must_use = "a disposition is what happened to a kind, and silence is not a variant"]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Disposition {
Generated {
unit: Identity<GeneratedUnit>,
},
NotApplicable {
because: OwnerFact,
},
NotRequested {
because: OwnerFact,
},
UnavailableUnderProfile {
profile: Profile,
because: OwnerFact,
},
}
pub trait DispositionRecord: Clone + Eq + core::fmt::Debug {
fn into_dispositions(self) -> impl Iterator<Item = (&'static str, Disposition)>;
}
pub trait KindSet {
type Dispositions: DispositionRecord;
const NAMES: &'static [&'static str];
}
#[must_use = "a complete disposition set is the witness an accounted expansion requires"]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DispositionSet<Set: KindSet> {
dispositions: Vec<Disposition>,
kind_set: PhantomData<fn() -> Set>,
}
#[must_use = "a disposition-set refusal names the count or kind-name disagreement"]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DispositionSetError {
CountMismatch {
expected: usize,
observed: usize,
},
KindMismatch {
expected: &'static str,
observed: &'static str,
},
}