Thanks to visit codestin.com
Credit goes to docs.rs

cursive_core/view/
finder.rs

1use crate::view::{View, ViewWrapper};
2use crate::views::{BoxedView, NamedView, ViewRef};
3
4/// Provides `call_on<V: View>` to views.
5///
6/// This trait is mostly a wrapper around [`View::call_on_any`].
7///
8/// It provides a nicer interface to find a view when you know its type.
9pub trait Finder {
10    /// Runs a callback on the view identified by `sel`.
11    ///
12    /// If the view is found, return the result of `callback`.
13    ///
14    /// If the view is not found, or if it is not of the asked type,
15    /// it returns `None`.
16    fn call_on<V, F, R>(&mut self, sel: &Selector, callback: F) -> Option<R>
17    where
18        V: View,
19        F: FnOnce(&mut V) -> R,
20    {
21        let mut callback = Some(callback);
22        let mut result = None;
23        self.call_on_all(sel, |v: &mut V| {
24            if let Some(callback) = callback.take() {
25                result = Some(callback(v));
26            }
27        });
28        result
29    }
30
31    /// Runs a callback on all views identified by `sel`.
32    ///
33    /// Useful if you have multiple views of the same type with the same name.
34    fn call_on_all<V, F>(&mut self, sel: &Selector, callback: F)
35    where
36        V: View,
37        F: FnMut(&mut V);
38
39    /// Convenient method to use `call_on` with a `view::Selector::Name`.
40    fn call_on_name<V, F, R>(&mut self, name: &str, callback: F) -> Option<R>
41    where
42        V: View,
43        F: FnOnce(&mut V) -> R,
44    {
45        self.call_on(&Selector::Name(name), callback)
46    }
47
48    /// Convenient method to find a view wrapped in an [`NamedView`].
49    fn find_name<V>(&mut self, name: &str) -> Option<ViewRef<V>>
50    where
51        V: View,
52    {
53        self.call_on_name(name, NamedView::<V>::get_mut)
54    }
55}
56
57impl<T: View> Finder for T {
58    fn call_on_all<V, F>(&mut self, sel: &Selector, mut callback: F)
59    where
60        V: View,
61        F: FnMut(&mut V),
62    {
63        self.call_on_any(sel, &mut |v: &mut dyn View| {
64            if let Some(v) = v.downcast_mut::<V>() {
65                // Allow to select the view directly.
66                callback(v);
67            } else if let Some(v) = v.downcast_mut::<NamedView<V>>() {
68                // In most cases we will actually find the wrapper.
69                v.with_view_mut(&mut callback);
70            } else if let Some(v) = v.downcast_mut::<NamedView<BoxedView>>() {
71                v.with_view_mut(|v: &mut BoxedView| {
72                    if let Some(v) = v.get_mut() {
73                        callback(v);
74                    }
75                });
76            }
77        });
78    }
79}
80
81/// Selects a single view (if any) in the tree.
82#[non_exhaustive]
83pub enum Selector<'a> {
84    /// Selects a view from its name.
85    Name(&'a str),
86}