From a0ae393db5c67e91549431c4357171aedec75b83 Mon Sep 17 00:00:00 2001 From: Zoey Bush Date: Sat, 29 Jun 2024 12:12:43 -0700 Subject: [PATCH 1/2] Export `Optionality` markers 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. --- crates/core/src/yarn_fn.rs | 2 +- crates/core/src/yarn_fn/optionality.rs | 15 ++++++++++++++- crates/yarnspinner/src/lib.rs | 8 ++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/crates/core/src/yarn_fn.rs b/crates/core/src/yarn_fn.rs index 51e4d176..4208fe6b 100644 --- a/crates/core/src/yarn_fn.rs +++ b/crates/core/src/yarn_fn.rs @@ -4,7 +4,7 @@ mod function_registry; mod function_wrapping; -mod optionality; +pub mod optionality; mod parameter_wrapping; pub(crate) use function_registry::*; diff --git a/crates/core/src/yarn_fn/optionality.rs b/crates/core/src/yarn_fn/optionality.rs index 981986f5..38bbc473 100644 --- a/crates/core/src/yarn_fn/optionality.rs +++ b/crates/core/src/yarn_fn/optionality.rs @@ -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; @@ -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 private::Sealed for (O,) {} impl AllowedOptionalityChain for (O,) { type Last = O; } +impl private::Sealed for (Required, O) {} impl AllowedOptionalityChain for (Required, O) { type Last = O; } +impl private::Sealed for (Optional, Optional) {} impl AllowedOptionalityChain for (Optional, Optional) { type Last = Optional; } @@ -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; } diff --git a/crates/yarnspinner/src/lib.rs b/crates/yarnspinner/src/lib.rs index 03182a10..ec882b57 100644 --- a/crates/yarnspinner/src/lib.rs +++ b/crates/yarnspinner/src/lib.rs @@ -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 { From 5df92b594d6de04fb54e1fd1cb8fa5f652b24e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tau=20G=C3=A4rtli?= Date: Sat, 29 Jun 2024 22:36:58 +0200 Subject: [PATCH 2/2] Seal Optionality trait --- crates/core/src/yarn_fn/optionality.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/core/src/yarn_fn/optionality.rs b/crates/core/src/yarn_fn/optionality.rs index 38bbc473..baa30245 100644 --- a/crates/core/src/yarn_fn/optionality.rs +++ b/crates/core/src/yarn_fn/optionality.rs @@ -5,17 +5,19 @@ 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 {