use slhx_core::{Atom, BuildFingerprint, Effect, EffectBatch, Form, IntoEffect, KeyedSlot, ResourceId, ResourceRef, Slot}; pub fn run(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(&self, slot: Slot) -> bool { self.has_resource(slot.id()) } pub fn has_keyed_slot(&self, slot: KeyedSlot) -> bool where K: ToString, { self.has_resource(slot.id()) } pub fn has_atom(&self, atom: Atom) -> bool { self.has_resource(atom.id()) } pub fn has_form(&self, form: Form) -> 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, } }