use super::stamp::named_vocabulary;
use crate::bounded::{Bounded, KeyedRoster};
use crate::diagnostic::{Diagnostic, Family};
use crate::expansion::Expansion;
use crate::identity::OwnerFact;
use crate::relation::{
AbsencePosture, CompletenessPosture, CyclePosture, DensityPosture, EmptyPosture,
MembershipPosture, RelationQuestion, RepetitionPosture, SelfRelationPosture,
};
use crate::render::Output;
use crate::request::Door;
use crate::support::SupportName;
use crate::token::{CapturedInput, GeneratedToken, GeneratedTree, SpanHandle};
#[path = "account/admit.rs"]
mod admit;
#[path = "account/collisions.rs"]
mod collisions;
#[path = "account/contracts.rs"]
mod contracts;
#[path = "account/informed.rs"]
mod informed;
#[path = "account/relation.rs"]
mod relation;
#[path = "account/restore.rs"]
mod restore;
#[path = "account/settle.rs"]
mod settle;
#[path = "type_guard.rs"]
mod guard;
pub(super) use super::issue::{ExactFunctionIssue, ExactProjectionSeat, RecipeError, RecipeIssue};
pub const VOCABULARY_LIMIT: usize = 64;
pub const RELATION_LIMIT: usize = 64;
pub const RELATION_ROW_LIMIT: usize = 128;
pub const RELATION_TABLE_LIMIT: usize = RELATION_LIMIT;
pub const TRANSITION_LIMIT: usize = RELATION_ROW_LIMIT;
pub const RELATION_QUESTION_LIMIT: usize = RelationQuestion::ALL.len();
pub const CODEC_LIMIT: usize = 16;
pub(super) const RECIPE_FAMILY: Family = Family::declared("macroonz/recipe");
pub(super) const RECIPE_FACT: OwnerFact = OwnerFact {
home: "recipe",
name: "one-informed-recipe-selects-and-delivers-every-requested-projection",
};
named_vocabulary! {
pub enum HarnessPosture {
Available = "available",
Unavailable = "unavailable",
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RecipeMember {
spelling: String,
name: GeneratedToken,
at: SpanHandle,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RecipeVocabulary {
name: String,
name_token: GeneratedToken,
members: KeyedRoster<RecipeMember, String, VOCABULARY_LIMIT>,
at: SpanHandle,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum RecipeRelationPayload {
Unlabeled,
Path(GeneratedTree),
ExactRust(GeneratedTree),
Transition {
target: String,
target_name: GeneratedToken,
effect: RecipeTransitionEffect,
},
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum RecipeTransitionEffect {
Path(GeneratedTree),
ExactRust {
target_binding: GeneratedToken,
body: GeneratedTree,
},
}
named_vocabulary! {
#[non_exhaustive]
pub enum RecipeRelationPayloadKind {
Unlabeled = "unlabeled",
Path = "path",
ExactRust = "exact-rust",
Transition = "transition",
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RecipeRelationRow {
left: String,
left_name: GeneratedToken,
left_at: SpanHandle,
right: String,
right_name: GeneratedToken,
right_at: SpanHandle,
payload: RecipeRelationPayload,
payload_at: SpanHandle,
effect_binding_at: Option<SpanHandle>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RecipeRelationRequirements {
empty: Option<EmptyPosture>,
repetition: Option<RepetitionPosture>,
membership: Option<[MembershipPosture; 2]>,
completeness: Option<[CompletenessPosture; 2]>,
density: Option<DensityPosture>,
absence: Option<AbsencePosture>,
self_relation: Option<SelfRelationPosture>,
cycle: Option<CyclePosture>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RecipeRelation {
name: String,
name_token: GeneratedToken,
name_at: SpanHandle,
left_vocabulary: String,
right_vocabulary: String,
rows: Bounded<RecipeRelationRow, RELATION_ROW_LIMIT>,
payload_kind: RecipeRelationPayloadKind,
requirements: RecipeRelationRequirements,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum RelationLowering {
Generic,
Transition,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RecipeCodec {
name: String,
content: crate::codec::CodecContent,
at: SpanHandle,
refusal_at: SpanHandle,
direction_at: SpanHandle,
}
crate::roster! {
#[non_exhaustive]
pub enum RecipeRole {
Companions = "companions",
RelationTables = "relation-tables",
Dispatch = "dispatch",
CompileContract = "compile-contract",
DeclarationConformance = "declaration-conformance",
Typestate = "typestate",
Trials = "trials",
Mutation = "mutation",
Benchmarks = "benchmarks",
Network = "network",
Concurrency = "concurrency",
Codec = "codec",
}
}
pub(super) const PROJECTION_ROLES: &[RecipeRole] = &[
RecipeRole::Companions,
RecipeRole::RelationTables,
RecipeRole::Dispatch,
RecipeRole::CompileContract,
RecipeRole::DeclarationConformance,
RecipeRole::Typestate,
RecipeRole::Codec,
];
pub(super) const EVIDENCE_ROLES: &[RecipeRole] = &[
RecipeRole::Trials,
RecipeRole::Mutation,
RecipeRole::Benchmarks,
RecipeRole::Network,
RecipeRole::Concurrency,
];
pub const PROJECTION_LIMIT: usize = RecipeRole::ALL.len();
pub const PROJECTION_CLAUSE_LIMIT: usize = PROJECTION_ROLES.len();
pub const EVIDENCE_LIMIT: usize = EVIDENCE_ROLES.len();
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum RecipeRoleEntrance {
Projection,
Evidence,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum RecipeRoleAvailability {
Always,
Harness,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum RecipeRolePlacement {
DeclarationRoot,
BakedModule,
SupportCarrier,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) struct RecipeRoleOutput {
pub(super) destination: crate::kind::Destination,
pub(super) placement: RecipeRolePlacement,
pub(super) placement_position: Option<usize>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) struct RecipeRoleProfile {
pub(super) position: usize,
pub(super) syntax: &'static str,
pub(super) entrance: RecipeRoleEntrance,
pub(super) availability: RecipeRoleAvailability,
pub(super) output: RecipeRoleOutput,
pub(super) evidence_position: Option<usize>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct EvidenceTarget {
vocabulary: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RecipeEvidence {
role: RecipeRole,
target: Option<EvidenceTarget>,
body: CapturedInput,
at: SpanHandle,
}
pub(crate) struct PreparedEvidence {
pub(super) trees: [Option<GeneratedTree>; EVIDENCE_LIMIT],
}
pub(crate) trait EvidenceCompiler {
fn prepared(
capture: &CapturedInput,
recipe: &Recipe,
door: &Door,
replaced: &[RecipeRole],
) -> Result<PreparedEvidence, Diagnostic>;
}
pub(crate) struct ConfiguredEvidence;
named_vocabulary! {
#[non_exhaustive]
pub enum LoweringSource {
Preset = "preset",
Configuration = "configuration",
ExactRust = "exact-rust",
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct EffectiveProjection {
role: RecipeRole,
name: Option<String>,
subject: Option<String>,
source: LoweringSource,
exact_rust: Option<GeneratedTree>,
exact_dispatch_bindings: Option<[GeneratedToken; 2]>,
exact_dispatch_binding_names: Option<Box<[String; 2]>>,
exact_dispatch_imports: Option<[bool; 2]>,
relation_tables: Option<Box<Bounded<RelationTableProjection, RELATION_TABLE_LIMIT>>>,
at: SpanHandle,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RelationTableProjection {
relation: String,
function: String,
source: LoweringSource,
exact_rust: Option<GeneratedTree>,
bindings: Option<[GeneratedToken; 2]>,
imports: Option<[bool; 2]>,
at: SpanHandle,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub(super) enum ProjectionStanding {
Generated(EffectiveProjection),
NotRequested,
FeatureUnavailable,
TargetUnavailable,
}
named_vocabulary! {
pub enum ProjectionDisposition {
Generated = "generated",
NotRequested = "not-requested",
FeatureUnavailable = "feature-unavailable",
TargetUnavailable = "target-unavailable",
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Recipe {
module_name: String,
module_name_token: GeneratedToken,
module_head: GeneratedTree,
authored_body: GeneratedTree,
authored_declaration: GeneratedTree,
module_body_at: Option<SpanHandle>,
vocabularies: Option<KeyedRoster<RecipeVocabulary, String, VOCABULARY_LIMIT>>,
relations: Option<KeyedRoster<RecipeRelation, String, RELATION_LIMIT>>,
transition_relation: Option<String>,
codecs: Option<KeyedRoster<RecipeCodec, String, CODEC_LIMIT>>,
projections: [ProjectionStanding; PROJECTION_LIMIT],
evidence: [Option<RecipeEvidence>; EVIDENCE_LIMIT],
support: Option<SupportName>,
}
pub(super) struct RecipeParts {
pub(super) module_name: String,
pub(super) module_name_token: GeneratedToken,
pub(super) module_head: GeneratedTree,
pub(super) authored_body: GeneratedTree,
pub(super) authored_declaration: GeneratedTree,
pub(super) module_body_at: Option<SpanHandle>,
pub(super) vocabularies: Vec<RecipeVocabularyParts>,
pub(super) relations: Vec<RecipeRelationParts>,
pub(super) transition_relation: Option<String>,
pub(super) codecs: Vec<RecipeCodec>,
pub(super) projections: [ProjectionStanding; PROJECTION_LIMIT],
pub(super) evidence: [Option<RecipeEvidence>; EVIDENCE_LIMIT],
pub(super) support: Option<SupportName>,
}
pub(super) struct RecipeVocabularyParts {
pub(super) name: String,
pub(super) name_token: GeneratedToken,
pub(super) members: Vec<RecipeMember>,
pub(super) at: SpanHandle,
}
pub(super) struct RecipeRelationParts {
pub(super) name: String,
pub(super) name_token: GeneratedToken,
pub(super) name_at: SpanHandle,
pub(super) left_vocabulary: String,
pub(super) left_vocabulary_at: SpanHandle,
pub(super) right_vocabulary: String,
pub(super) right_vocabulary_at: SpanHandle,
pub(super) rows: Vec<RecipeRelationRow>,
pub(super) requirements: RecipeRelationRequirements,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RecipeProjection;
#[derive(Clone, Copy)]
pub struct RecipeView<'recipe> {
recipe: &'recipe Recipe,
}
#[derive(Clone, Copy)]
pub struct ProjectionRequest<'recipe> {
effective: &'recipe EffectiveProjection,
}
pub struct ProjectionSink<'output, 'plan> {
output: &'output mut Output<'plan, RecipeProjection>,
role: RecipeRole,
}
#[must_use = "a successful offer is evidence that the selected projection seat was filled"]
pub struct ProjectionOffered {
_private: (),
}
pub trait RecipeProjector {
fn project(
&self,
view: RecipeView<'_>,
request: ProjectionRequest<'_>,
sink: ProjectionSink<'_, '_>,
) -> Result<ProjectionOffered, ProjectionError>;
}
#[derive(Clone, Copy)]
pub struct ProjectorReplacement<'projector> {
role: RecipeRole,
projector: &'projector dyn RecipeProjector,
}
pub(super) struct StandardProjector<'evidence> {
pub(super) evidence: &'evidence PreparedEvidence,
}
#[must_use = "a projection refusal states why the selected role was not filled"]
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProjectionError {
Tokens(crate::bounded::Overflow),
Render(crate::render::RenderError),
}
#[must_use = "a baked recipe carries the selected projection expansion and its sealed emitted module"]
pub struct RecipeBake {
pub(super) projection: Expansion<RecipeProjection>,
pub(super) emitted: Expansion<RecipeShell>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) struct RecipeShell;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) struct RecipeShellContent {
pub(super) recipe: crate::identity::ClosedExpansionId,
pub(super) support: Option<crate::identity::ClosedExpansionId>,
}