use crate::descriptor::PopulationRef;
use crate::identity::{DomainTag, IdentityProfileVersion};
use crate::report::{ByteBudget, CaseBudget, GenerationProfile};
use arbitrary::Unstructured;
use std::num::NonZeroU32;
macro_rules! with_generation_dispositions {
($callback:ident) => {
$callback! {
Generated => generated,
BytesInsufficient => bytes_insufficient,
PreconditionRejected => precondition_rejected,
GeneratorRefused => generator_refused,
GeneratorContractViolated => generator_contract_violated,
GenerationBudgetExhausted => budget_exhausted,
}
};
}
macro_rules! declare_generation_dispositions {
($($(#[$variant_meta:meta])* $variant:ident => $seat:ident),+ $(,)?) => {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum GenerationDisposition {
$($(#[$variant_meta])* $variant),+
}
pub const GENERATION_DISPOSITION_SEATS: usize = [
$(GenerationDisposition::$variant),+
]
.len();
crate::census::declare_census! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct GenerationCensus {
count: u32,
seat: GenerationCensusSeat,
context { population: PopulationRef, }
array counts [GENERATION_DISPOSITION_SEATS] {
$( $variant => $seat, )+
}
}
}
};
}
with_generation_dispositions!(declare_generation_dispositions);
#[path = "type_guard.rs"]
mod guard;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RootSeed(u64);
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum InputOrigin {
Seeded(RootSeed),
Supplied(Vec<u8>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CaseWidth(usize);
#[must_use = "a refusal is the reason a case width was not built"]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CaseWidthRefusal {
ZeroBytes,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SizeProgression {
Constant {
width: CaseWidth,
},
Linear {
base: CaseWidth,
step: CaseWidth,
},
Doubling {
base: CaseWidth,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CaseIndex(u32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum RejectionAllowance {
NoRejections,
AtMost(NonZeroU32),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GenerationPlan {
population: PopulationRef,
profile: GenerationProfile,
origin: InputOrigin,
cases: CaseBudget,
bytes: ByteBudget,
rejection_allowance: RejectionAllowance,
progression: SizeProgression,
}
#[must_use = "a refusal is the reason a generation plan was not built"]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum GenerationPlanRefusal {
ZeroCaseBudget,
ZeroByteBudget,
EmptySuppliedBytes,
}
pub const GENERATION_SOURCE_TAG: DomainTag = DomainTag::declared(
"generation-byte-source",
IdentityProfileVersion::declared(1),
);
pub const GENERATION_CHUNK_TAG: DomainTag = DomainTag::declared(
"generation-stream-chunk",
IdentityProfileVersion::declared(1),
);
pub const SOURCE_CHUNK_BYTES: usize = 32;
crate::identity::content_address_reference! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ByteSourceAddress;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct StreamCursor {
chunk: u64,
within: usize,
}
#[must_use = "a refusal is the reason a stream cursor was not built"]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum StreamCursorRefusal {
WithinPastChunk {
within: usize,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ByteSource {
Derived(ByteSourceAddress),
Supplied(Vec<u8>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ByteDraw {
Drawn {
bytes: Vec<u8>,
next: StreamCursor,
},
Insufficient {
requested: usize,
available: usize,
},
}
pub type CommandDecode<Command> = fn(&mut Unstructured<'_>) -> arbitrary::Result<Command>;
pub type SequencePrecondition<Command> = fn(&[Command]) -> PreconditionVerdict;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PreconditionVerdict {
Admitted,
Rejected,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CommandSequence<Command> {
case: CaseIndex,
commands: Vec<Command>,
input: Vec<u8>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum GenerationHalt {
CaseBudgetMet,
ByteBudgetExhausted,
RejectionAllowanceSpent,
SourceExhausted,
GeneratorContractViolated,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GeneratedSequences<Command> {
sequences: Vec<CommandSequence<Command>>,
census: GenerationCensus,
halt: GenerationHalt,
}