89 lines
2.3 KiB
Rust
89 lines
2.3 KiB
Rust
use slhx_core::{Atom, BuildFingerprint, Effect, EffectBatch, Form, IntoEffect, KeyedSlot, ResourceId, ResourceRef, Slot};
|
|
|
|
pub fn run<I, F, R>(handler: F, input: I) -> EffectInspector
|
|
where
|
|
F: FnOnce(I) -> R,
|
|
R: IntoEffect,
|
|
{
|
|
inspect(handler(input))
|
|
}
|
|
|
|
pub fn inspect(effect: impl IntoEffect) -> EffectInspector {
|
|
EffectInspector {
|
|
batch: effect.into_batch(BuildFingerprint(0)),
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct EffectInspector {
|
|
batch: EffectBatch,
|
|
}
|
|
|
|
impl EffectInspector {
|
|
pub fn batch(&self) -> &EffectBatch {
|
|
&self.batch
|
|
}
|
|
|
|
pub fn ops(&self) -> &[Effect] {
|
|
&self.batch.ops
|
|
}
|
|
|
|
pub fn contains(&self, op: &Effect) -> bool {
|
|
self.batch.ops.contains(op)
|
|
}
|
|
|
|
pub fn has_resource(&self, resource: ResourceId) -> bool {
|
|
self.batch
|
|
.ops
|
|
.iter()
|
|
.any(|op| op_targets_resource(op, resource))
|
|
}
|
|
|
|
pub fn has_ref(&self, target: &ResourceRef) -> bool {
|
|
self.batch.ops.iter().any(|op| op_targets_ref(op, target))
|
|
}
|
|
|
|
pub fn has_slot<T>(&self, slot: Slot<T>) -> bool {
|
|
self.has_resource(slot.id())
|
|
}
|
|
|
|
pub fn has_keyed_slot<K, T>(&self, slot: KeyedSlot<K, T>) -> bool
|
|
where
|
|
K: ToString,
|
|
{
|
|
self.has_resource(slot.id())
|
|
}
|
|
|
|
pub fn has_atom<T>(&self, atom: Atom<T>) -> bool {
|
|
self.has_resource(atom.id())
|
|
}
|
|
|
|
pub fn has_form<T>(&self, form: Form<T>) -> bool {
|
|
self.has_resource(form.id())
|
|
}
|
|
}
|
|
|
|
fn op_targets_resource(op: &Effect, resource: ResourceId) -> bool {
|
|
match op {
|
|
Effect::Put { target, .. }
|
|
| Effect::Insert { target, .. }
|
|
| Effect::Prepend { target, .. }
|
|
| Effect::Remove { target, .. }
|
|
| Effect::Move { target, .. }
|
|
| Effect::Focus { target } => target.resource == resource,
|
|
Effect::Navigate { .. } | Effect::Emit { .. } => false,
|
|
}
|
|
}
|
|
|
|
fn op_targets_ref(op: &Effect, wanted: &ResourceRef) -> bool {
|
|
match op {
|
|
Effect::Put { target, .. }
|
|
| Effect::Insert { target, .. }
|
|
| Effect::Prepend { target, .. }
|
|
| Effect::Remove { target, .. }
|
|
| Effect::Move { target, .. }
|
|
| Effect::Focus { target } => target == wanted,
|
|
Effect::Navigate { .. } | Effect::Emit { .. } => false,
|
|
}
|
|
}
|