Skip to content

Commit

Permalink
Implement Debug for EventResult and EventTrigger
Browse files Browse the repository at this point in the history
  • Loading branch information
gyscos committed Aug 28, 2024
1 parent fe88657 commit 30389f3
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions cursive-core/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,34 @@ pub type AnyCb<'a> = &'a mut dyn FnMut(&mut dyn crate::view::View);
///
/// It is meant to be stored in views.
pub struct EventTrigger {
// A function called on each individual event to know if it applies.
trigger: Box<dyn Fn(&Event) -> bool + Send + Sync>,

// Some marker to indicate the origin.
//
// In practice it could be a `&'static str` describing the trigger, or an `Event` for
// single-event triggers.
//
// TODO: Require `Debug` on the tag, so we could implement `Debug` for `EventTrigger`?
tag: Box<dyn AnyTag + Send + Sync>,
}

impl std::fmt::Debug for EventTrigger {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// For some well-known types we can print something.
if let Some(event) = self.tag.as_any().downcast_ref::<Event>() {
return write!(f, "EventTrigger {{ {event:?} }}");
}

if let Some(str) = self.tag.as_any().downcast_ref::<&'static str>() {
return write!(f, "EventTrigger {{ {str:?} }}");
}

// But in the general case right now we can only guess
f.write_str("EventTrigger { ? }")
}
}

trait AnyTag: Any + std::fmt::Debug {
fn as_any(&self) -> &dyn Any;
}
Expand Down Expand Up @@ -242,6 +266,16 @@ pub enum EventResult {
Consumed(Option<Callback>), // TODO: make this a FnOnce?
}

impl std::fmt::Debug for EventResult {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EventResult::Ignored => f.write_str("EventResult::Ignored"),
EventResult::Consumed(None) => f.write_str("EventResult::Consumed(None)"),
EventResult::Consumed(_) => f.write_str("EventResult::Consumed(Some(_))"),
}
}
}

impl EventResult {
/// Convenient method to create `Consumed(Some(f))`
pub fn with_cb<F>(f: F) -> Self
Expand Down Expand Up @@ -312,6 +346,25 @@ impl EventResult {
}
}
}

/// Combines the given event results into a single one.
///
/// If `results` is empty or if all results are `Ignored`, returns `Ignored`.
///
/// Otherwise, returns a callback that runs all callback in results.
pub fn combine(results: Vec<Self>) -> Self {
if results.iter().all(|result| !result.is_consumed()) {
return EventResult::Ignored;
}

// TODO: if all events are `Ignored` or `Consumed(None)`,
// returns `Consumed(None)` and save the allocation?
EventResult::with_cb_once(move |siv| {
for res in results {
res.process(siv);
}
})
}
}

/// A non-character key on the keyboard
Expand Down

0 comments on commit 30389f3

Please sign in to comment.