Skip to content

Commit

Permalink
Merge pull request #203 from zmbush/expose-optionality
Browse files Browse the repository at this point in the history
  • Loading branch information
janhohenheim authored Jun 29, 2024
2 parents 0f2d488 + 5df92b5 commit da56041
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 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
19 changes: 17 additions & 2 deletions crates/core/src/yarn_fn/optionality.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,55 @@
//! Marker traits for [`super::YarnFnParam`] to determine if the type is [`Required`] or
//! [`Optional`].
#![allow(missing_debug_implementations)]

use yarnspinner_macros::all_tuples;

/// Marker trait for valid optionality hints.
pub trait Optionality {}
pub trait Optionality: private::Sealed {}

/// An optional parameter or a tuple where
/// the last element is optional.
pub struct Optional;

impl private::Sealed for Optional {}
impl Optionality for Optional {}

/// A parameter that is required.
pub struct Required;

impl private::Sealed for 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 +75,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 da56041

Please sign in to comment.