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,
}
}
#[must_use]
pub const fn role(&self) -> RecipeRole {
self.role
}
#[must_use]
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
#[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);
}
#[must_use]
pub const fn source(&self) -> LoweringSource {
self.source
}
#[must_use]
pub const fn exact_rust(&self) -> Option<&GeneratedTree> {
self.exact_rust.as_ref()
}
#[must_use]
pub const fn dispatch_binding_tokens(&self) -> Option<&[crate::token::GeneratedToken; 2]> {
self.exact_dispatch_bindings.as_ref()
}
#[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()])
}
#[must_use]
pub const fn dispatch_subject_imports(&self) -> Option<[bool; 2]> {
self.exact_dispatch_imports
}
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,
}
}
#[must_use]
pub fn relation(&self) -> &str {
self.relation.as_str()
}
#[must_use]
pub fn function(&self) -> &str {
self.function.as_str()
}
#[must_use]
pub const fn source(&self) -> LoweringSource {
self.source
}
pub(in crate::recipe) const fn at(&self) -> SpanHandle {
self.at
}
#[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 }
}
#[must_use]
pub const fn recipe(self) -> &'recipe Recipe {
self.recipe
}
}
impl<'projector> ProjectorReplacement<'projector> {
#[must_use]
pub const fn for_role(
role: RecipeRole,
projector: &'projector dyn super::RecipeProjector,
) -> Self {
Self { role, projector }
}
#[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 }
}
#[must_use]
pub const fn role(self) -> RecipeRole {
self.effective.role()
}
#[must_use]
pub const fn effective(self) -> &'recipe EffectiveProjection {
self.effective
}
#[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 }
}
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,
}
}
pub const fn projection(&self) -> &Expansion<RecipeProjection> {
&self.projection
}
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 }
}
}