Add Joined combinator

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2025-11-04 13:51:28 +01:00
parent 44e8280093
commit edc076efdd
2 changed files with 127 additions and 17 deletions

View file

@ -48,6 +48,10 @@ impl InternalMessage {
pub fn type_name(&self) -> &'static str {
self.name
}
pub fn type_id(&self) -> TypeId {
self.value.as_ref().type_id()
}
}
pub trait Address<MB> {
@ -116,6 +120,7 @@ pub struct BundleChain {
pub enum BundleOp {
Add(TypeId),
Remove(TypeId),
Chain(&'static BundleChain),
}
impl BundleChain {
@ -126,12 +131,31 @@ impl BundleChain {
}
}
pub const fn contains(&self, id: TypeId) -> bool {
check_is_contained(self, id)
}
pub const fn with<M: Message>(&'static self) -> BundleChain {
add_to_chain(self, TypeId::of::<M>())
let to_add = TypeId::of::<M>();
BundleChain {
op: BundleOp::Add(to_add),
next: Some(self),
}
}
pub const fn without<M: Message>(&'static self) -> BundleChain {
remove_from_chain(self, TypeId::of::<M>())
let to_remove = TypeId::of::<M>();
BundleChain {
op: BundleOp::Remove(to_remove),
next: Some(self),
}
}
pub const fn join(&'static self, ids: &'static BundleChain) -> BundleChain {
BundleChain {
op: BundleOp::Chain(self),
next: Some(ids),
}
}
}
@ -165,7 +189,7 @@ where
const IS_CONTAINED: bool = check_is_contained(&MB::IDS, TypeId::of::<M>());
}
const fn check_is_contained(ids: &'static BundleChain, id: TypeId) -> bool {
const fn check_is_contained(ids: &BundleChain, id: TypeId) -> bool {
match ids.op {
BundleOp::Add(added_id) => {
if check_type_id_equal(added_id, id) {
@ -177,6 +201,11 @@ const fn check_is_contained(ids: &'static BundleChain, id: TypeId) -> bool {
return false;
}
}
BundleOp::Chain(other_chain) => {
if check_is_contained(other_chain, id) {
return true;
}
}
}
if let Some(next) = ids.next {
@ -190,20 +219,6 @@ const fn check_type_id_equal(left: TypeId, right: TypeId) -> bool {
left == right
}
const fn add_to_chain(prev: &'static BundleChain, to_add: TypeId) -> BundleChain {
BundleChain {
op: BundleOp::Add(to_add),
next: Some(prev),
}
}
const fn remove_from_chain(prev: &'static BundleChain, to_remove: TypeId) -> BundleChain {
BundleChain {
op: BundleOp::Remove(to_remove),
next: Some(prev),
}
}
#[cfg(test)]
mod tests {
use macro_rules_attribute::apply;