Skip to content

Commit

Permalink
Export Optionality markers
Browse files Browse the repository at this point in the history
In order to support custom implementations of `YarnFnParam`, `Optional`
and `Required` need to be exported.

This exports `yarnspinner_core::yarn_fn::optionality` as
`yarnspinner_core::prelude::optionality` and seals the
`AllowedOptionalityChain` trait so it cannot be implemented.
  • Loading branch information
zmbush committed Jun 29, 2024
1 parent 0f2d488 commit a0ae393
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
2 changes: 1 addition & 1 deletion crates/core/src/yarn_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
mod function_registry;
mod function_wrapping;
mod optionality;
pub mod optionality;
mod parameter_wrapping;

pub(crate) use function_registry::*;
Expand Down
15 changes: 14 additions & 1 deletion crates/core/src/yarn_fn/optionality.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Marker traits for [`super::YarnFnParam`] to determine if the type is [`Required`] or
//! [`Optional`].
#![allow(missing_debug_implementations)]

use yarnspinner_macros::all_tuples;
Expand All @@ -16,26 +18,36 @@ pub struct Required;

impl Optionality for Required {}

mod private {
/// Used to seal [`AllowedOptionalityChain`] so the type can be exported,
/// but not implemented.
pub trait Sealed {}
}

/// A valid chain of optionality hints
/// i.e. a chain where no optional element follows
/// a required element.
pub trait AllowedOptionalityChain {
pub trait AllowedOptionalityChain: private::Sealed {
/// The optionality hint of the last element in the chain.
type Last: Optionality;
}

impl private::Sealed for () {}
impl AllowedOptionalityChain for () {
type Last = Required;
}

impl<O: Optionality> private::Sealed for (O,) {}
impl<O: Optionality> AllowedOptionalityChain for (O,) {
type Last = O;
}

impl<O: Optionality> private::Sealed for (Required, O) {}
impl<O: Optionality> AllowedOptionalityChain for (Required, O) {
type Last = O;
}

impl private::Sealed for (Optional, Optional) {}
impl AllowedOptionalityChain for (Optional, Optional) {
type Last = Optional;
}
Expand All @@ -61,6 +73,7 @@ macro_rules! impl_chain {
impl_chain!(@pairwise [$($param),*] [$($tt)* ($a, $b): AllowedOptionalityChain,] $b, $($tail,)*);
};
(@emit [$($param: ident),*] [$($tt:tt)*] $last:ident,) => {
impl<$($param: Optionality),*> private::Sealed for ($($param),*) where $($tt)* {}
impl<$($param: Optionality),*> AllowedOptionalityChain for ($($param),*) where $($tt)* {
type Last = $last;
}
Expand Down
8 changes: 4 additions & 4 deletions crates/yarnspinner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ pub mod prelude {
pub mod core {
//! Core types and traits that are used by both the compiler and runtime.
pub use yarnspinner_core::prelude::{
yarn_fn_type, yarn_library, Header, Instruction, IntoYarnValueFromNonYarnValue,
InvalidOpCodeError, Library, LineId, Node, Position, Program, Type, UntypedYarnFn, YarnFn,
YarnFnParam, YarnFnParamItem, YarnValue, YarnValueCastError, YarnValueWrapper,
YarnValueWrapperIter,
optionality, yarn_fn_type, yarn_library, Header, Instruction,
IntoYarnValueFromNonYarnValue, InvalidOpCodeError, Library, LineId, Node, Position,
Program, Type, UntypedYarnFn, YarnFn, YarnFnParam, YarnFnParamItem, YarnValue,
YarnValueCastError, YarnValueWrapper, YarnValueWrapperIter,
};
}
pub mod compiler {
Expand Down

0 comments on commit a0ae393

Please sign in to comment.