macroonz-compiler 0.2.0

Deterministic Rust code generation for procedural macros: plan, render, close, explain, and bind one sealed expansion from declared input.
Documentation
//! Projection capabilities and baked-recipe readback.

use super::{
    EffectiveProjection, LoweringSource, ProjectionError, ProjectionOffered, ProjectionRequest,
    ProjectionSink, ProjectorReplacement, RELATION_TABLE_LIMIT, Recipe, RecipeBake,
    RecipeProjection, RecipeRole, RecipeShell, RecipeShellContent, RecipeView,
    RelationTableProjection,
};
use crate::bounded::Bounded;
use crate::expansion::Expansion;
use crate::kind::Role;
use crate::render::Output;
use crate::token::{GeneratedTree, SpanHandle};

impl EffectiveProjection {
    pub(in crate::recipe) fn effective(
        role: RecipeRole,
        name: Option<String>,
        subject: Option<String>,
        source: LoweringSource,
        at: SpanHandle,
    ) -> Self {
        Self {
            role,
            name,
            subject,
            source,
            exact_rust: None,
            exact_dispatch_bindings: None,
            exact_dispatch_binding_names: None,
            exact_dispatch_imports: None,
            relation_tables: None,
            at,
        }
    }

    pub(in crate::recipe) fn exact_dispatch(
        name: String,
        exact_rust: GeneratedTree,
        bindings: [crate::token::GeneratedToken; 2],
        binding_names: [String; 2],
        imports: [bool; 2],
        at: SpanHandle,
    ) -> Self {
        Self {
            role: RecipeRole::Dispatch,
            name: Some(name),
            subject: None,
            source: LoweringSource::ExactRust,
            exact_rust: Some(exact_rust),
            exact_dispatch_bindings: Some(bindings),
            exact_dispatch_binding_names: Some(Box::new(binding_names)),
            exact_dispatch_imports: Some(imports),
            relation_tables: None,
            at,
        }
    }

    pub(in crate::recipe) fn with_relation_tables(
        tables: Bounded<RelationTableProjection, RELATION_TABLE_LIMIT>,
        at: SpanHandle,
    ) -> Self {
        Self {
            role: RecipeRole::RelationTables,
            name: None,
            subject: None,
            source: LoweringSource::Configuration,
            exact_rust: None,
            exact_dispatch_bindings: None,
            exact_dispatch_binding_names: None,
            exact_dispatch_imports: None,
            relation_tables: Some(Box::new(tables)),
            at,
        }
    }

    /// Reads the selected role.
    #[must_use]
    pub const fn role(&self) -> RecipeRole {
        self.role
    }

    /// Reads the effective public spelling where this role declares one.
    #[must_use]
    pub fn name(&self) -> Option<&str> {
        self.name.as_deref()
    }

    /// Reads the informed structural subject selected for this projection.
    #[must_use]
    pub fn subject(&self) -> Option<&str> {
        self.subject.as_deref()
    }

    pub(in crate::recipe) fn select_subject(&mut self, subject: String) {
        self.subject = Some(subject);
    }

    /// Reads where the effective value came from.
    #[must_use]
    pub const fn source(&self) -> LoweringSource {
        self.source
    }

    /// Reads the exact caller-authored Rust that replaced this mechanical seat.
    #[must_use]
    pub const fn exact_rust(&self) -> Option<&GeneratedTree> {
        self.exact_rust.as_ref()
    }

    /// Reads the exact state and event binding tokens selected for an exact dispatch body.
    #[must_use]
    pub const fn dispatch_binding_tokens(&self) -> Option<&[crate::token::GeneratedToken; 2]> {
        self.exact_dispatch_bindings.as_ref()
    }

    /// Reads the state and event parameter bindings selected for an exact dispatch body.
    #[must_use]
    pub fn dispatch_bindings(&self) -> Option<[&str; 2]> {
        self.exact_dispatch_binding_names
            .as_deref()
            .map(|[state, event]| [state.as_str(), event.as_str()])
    }

    /// Reads whether an exact dispatch signature requires each transition vocabulary in scope.
    #[must_use]
    pub const fn dispatch_subject_imports(&self) -> Option<[bool; 2]> {
        self.exact_dispatch_imports
    }

    /// Reads every selected relation-table surface in declaration order.
    pub fn relation_tables(&self) -> impl Iterator<Item = &RelationTableProjection> {
        self.relation_tables.iter().flat_map(|tables| tables.iter())
    }

    pub(in crate::recipe) const fn at(&self) -> SpanHandle {
        self.at
    }
}

impl RelationTableProjection {
    pub(in crate::recipe) fn informed(
        relation: String,
        function: String,
        source: LoweringSource,
        exact_rust: Option<GeneratedTree>,
        bindings: Option<[crate::token::GeneratedToken; 2]>,
        imports: Option<[bool; 2]>,
        at: SpanHandle,
    ) -> Self {
        Self {
            relation,
            function,
            source,
            exact_rust,
            bindings,
            imports,
            at,
        }
    }

    /// Reads the caller-named relation selected by this table.
    #[must_use]
    pub fn relation(&self) -> &str {
        self.relation.as_str()
    }

    /// Reads the effective function name inside the relation-named module.
    #[must_use]
    pub fn function(&self) -> &str {
        self.function.as_str()
    }

    /// Reads where this function surface came from.
    #[must_use]
    pub const fn source(&self) -> LoweringSource {
        self.source
    }

    pub(in crate::recipe) const fn at(&self) -> SpanHandle {
        self.at
    }

    /// Reads the exact caller-authored function signature where one was supplied.
    #[must_use]
    pub const fn exact_rust(&self) -> Option<&GeneratedTree> {
        self.exact_rust.as_ref()
    }

    pub(in crate::recipe) const fn bindings(&self) -> Option<&[crate::token::GeneratedToken; 2]> {
        self.bindings.as_ref()
    }

    pub(in crate::recipe) const fn imports(&self) -> Option<&[bool; 2]> {
        self.imports.as_ref()
    }
}

impl<'recipe> RecipeView<'recipe> {
    pub(in crate::recipe) const fn over(recipe: &'recipe Recipe) -> Self {
        Self { recipe }
    }

    /// Reads the informed recipe without plan or mutation authority.
    #[must_use]
    pub const fn recipe(self) -> &'recipe Recipe {
        self.recipe
    }
}

impl<'projector> ProjectorReplacement<'projector> {
    /// Bind one caller-owned projector to one selected role for one bake.
    #[must_use]
    pub const fn for_role(
        role: RecipeRole,
        projector: &'projector dyn super::RecipeProjector,
    ) -> Self {
        Self { role, projector }
    }

    /// Reads the selected role this caller-owned projector replaces.
    #[must_use]
    pub const fn role(self) -> RecipeRole {
        self.role
    }

    pub(in crate::recipe) const fn projector(self) -> &'projector dyn super::RecipeProjector {
        self.projector
    }
}

impl<'recipe> ProjectionRequest<'recipe> {
    pub(in crate::recipe) const fn selected(effective: &'recipe EffectiveProjection) -> Self {
        Self { effective }
    }

    /// Reads the exact selected role this invocation answers.
    #[must_use]
    pub const fn role(self) -> RecipeRole {
        self.effective.role()
    }

    /// Reads the complete effective mechanical configuration for this invocation.
    #[must_use]
    pub const fn effective(self) -> &'recipe EffectiveProjection {
        self.effective
    }

    /// Reads the destination owned by the selected role.
    #[must_use]
    pub fn destination(self) -> crate::kind::Destination {
        self.role().destination()
    }
}

impl<'output, 'plan> ProjectionSink<'output, 'plan> {
    pub(in crate::recipe) const fn bound(
        output: &'output mut Output<'plan, RecipeProjection>,
        role: RecipeRole,
    ) -> Self {
        Self { output, role }
    }

    /// Offers one tree under the exact role bound into this one-use capability.
    ///
    /// # Errors
    ///
    /// Returns the existing output refusal when the plan does not admit the role or the rendered bytes exceed their bound.
    pub fn offer(self, tree: GeneratedTree) -> Result<ProjectionOffered, ProjectionError> {
        self.output
            .unit(self.role, tree)
            .map_err(ProjectionError::Render)?;
        Ok(ProjectionOffered { _private: () })
    }
}

impl RecipeBake {
    pub(in crate::recipe) const fn baked(
        projection: Expansion<RecipeProjection>,
        emitted: Expansion<RecipeShell>,
    ) -> Self {
        Self {
            projection,
            emitted,
        }
    }

    /// Reads the selected projection expansion before final module assembly.
    pub const fn projection(&self) -> &Expansion<RecipeProjection> {
        &self.projection
    }

    /// Reads the proved declaration-site cargo emitted by the paved proc host.
    pub fn emit(&self) -> &crate::closure::PartitionCargo {
        self.emitted.emit()
    }
}

impl RecipeShellContent {
    pub(in crate::recipe) const fn composed(
        recipe: crate::identity::ClosedExpansionId,
        support: Option<crate::identity::ClosedExpansionId>,
    ) -> Self {
        Self { recipe, support }
    }
}