pub struct ErrorBoundaryBuilder { /* private fields */ }Expand description
Builder for error boundary views.
Implementations§
Source§impl ErrorBoundaryBuilder
impl ErrorBoundaryBuilder
pub fn new() -> Self
Sourcepub fn child(self, child: View) -> Self
pub fn child(self, child: View) -> Self
Set the child view (the view that might panic).
Examples found in repository?
examples/37_error_boundary.rs (line 71)
38 fn render(&self, cx: Scope) -> View {
39 let show_help = state!(cx, || false);
40
41 cx.use_command(
42 KeyBinding::key(KeyCode::F(1)),
43 with!(show_help => move || show_help.update(|v| *v = !*v)),
44 );
45
46 let count = state!(cx, || 0i32);
47
48 // The panic must happen at render time (inside render_view) so the
49 // error boundary's catch_unwind can catch it. A custom widget defers
50 // execution to the render pass.
51 let risky_view = View::custom(std::rc::Rc::new(std::cell::RefCell::new(RiskyCounter(count.get()))));
52
53 let fallback = View::vstack()
54 .child(View::styled_text("CAUGHT PANIC").color(Color::Red).bold().build())
55 .child(View::text("The child view panicked."))
56 .child(View::text("But the app is still running!"))
57 .build();
58
59 View::vstack()
60 .spacing(1)
61 .child(View::styled_text("Error Boundary Demo").bold().build())
62 .child(
63 View::hstack()
64 .spacing(2)
65 .child(
66 View::vstack()
67 .spacing(1)
68 .child(View::styled_text("Protected Panel").bold().build())
69 .child(
70 View::error_boundary()
71 .child(risky_view)
72 .fallback(fallback)
73 .build(),
74 )
75 .build(),
76 )
77 .child(
78 View::vstack()
79 .spacing(1)
80 .child(View::styled_text("How It Works").bold().build())
81 .child(View::text("The left panel asserts"))
82 .child(View::text("count < 5. When it hits"))
83 .child(View::text("5, the error boundary"))
84 .child(View::text("catches the panic and"))
85 .child(View::text("renders the fallback."))
86 .build(),
87 )
88 .build(),
89 )
90 .child(
91 View::hstack()
92 .spacing(1)
93 .child(
94 View::button()
95 .label("[ + Increment ]")
96 .on_press(with!(count => move || count.update(|n| *n += 1)))
97 .build(),
98 )
99 .child(
100 View::button()
101 .label("[ Reset to 0 ]")
102 .on_press(with!(count => move || count.set(0)))
103 .build(),
104 )
105 .child(View::styled_text(format!("count = {}", count.get())).dim().build())
106 .build(),
107 )
108 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
109 .child(
110 View::modal()
111 .visible(show_help.get())
112 .title("Example 37: Error Boundary")
113 .on_dismiss(with!(show_help => move || show_help.set(false)))
114 .child(
115 View::vstack()
116 .child(View::styled_text("What you're seeing").bold().build())
117 .child(View::text("• A counter that panics at 5"))
118 .child(View::text("• Error boundary catches the panic"))
119 .child(View::text("• Red fallback replaces the crash"))
120 .child(View::gap(1))
121 .child(View::styled_text("Key concepts").bold().build())
122 .child(View::text("• View::error_boundary()"))
123 .child(View::text("• .child(risky) .fallback(safe)"))
124 .child(View::text("• Panics are caught, not propagated"))
125 .child(View::text("• App keeps running after panic"))
126 .child(View::gap(1))
127 .child(View::styled_text("Try this").bold().build())
128 .child(View::text("• Increment to 5 to trigger panic"))
129 .child(View::text("• Reset to 0 to recover"))
130 .child(View::text("• Keep incrementing past 5"))
131 .child(View::gap(1))
132 .child(View::styled_text("Next up").bold().build())
133 .child(View::text("-> 38_custom_widget: Game of Life"))
134 .child(View::gap(1))
135 .child(View::styled_text("Press Escape to close").dim().build())
136 .build(),
137 )
138 .build(),
139 )
140 .build()
141 }Sourcepub fn fallback(self, fallback: View) -> Self
pub fn fallback(self, fallback: View) -> Self
Set the fallback view (shown when child panics).
Examples found in repository?
examples/37_error_boundary.rs (line 72)
38 fn render(&self, cx: Scope) -> View {
39 let show_help = state!(cx, || false);
40
41 cx.use_command(
42 KeyBinding::key(KeyCode::F(1)),
43 with!(show_help => move || show_help.update(|v| *v = !*v)),
44 );
45
46 let count = state!(cx, || 0i32);
47
48 // The panic must happen at render time (inside render_view) so the
49 // error boundary's catch_unwind can catch it. A custom widget defers
50 // execution to the render pass.
51 let risky_view = View::custom(std::rc::Rc::new(std::cell::RefCell::new(RiskyCounter(count.get()))));
52
53 let fallback = View::vstack()
54 .child(View::styled_text("CAUGHT PANIC").color(Color::Red).bold().build())
55 .child(View::text("The child view panicked."))
56 .child(View::text("But the app is still running!"))
57 .build();
58
59 View::vstack()
60 .spacing(1)
61 .child(View::styled_text("Error Boundary Demo").bold().build())
62 .child(
63 View::hstack()
64 .spacing(2)
65 .child(
66 View::vstack()
67 .spacing(1)
68 .child(View::styled_text("Protected Panel").bold().build())
69 .child(
70 View::error_boundary()
71 .child(risky_view)
72 .fallback(fallback)
73 .build(),
74 )
75 .build(),
76 )
77 .child(
78 View::vstack()
79 .spacing(1)
80 .child(View::styled_text("How It Works").bold().build())
81 .child(View::text("The left panel asserts"))
82 .child(View::text("count < 5. When it hits"))
83 .child(View::text("5, the error boundary"))
84 .child(View::text("catches the panic and"))
85 .child(View::text("renders the fallback."))
86 .build(),
87 )
88 .build(),
89 )
90 .child(
91 View::hstack()
92 .spacing(1)
93 .child(
94 View::button()
95 .label("[ + Increment ]")
96 .on_press(with!(count => move || count.update(|n| *n += 1)))
97 .build(),
98 )
99 .child(
100 View::button()
101 .label("[ Reset to 0 ]")
102 .on_press(with!(count => move || count.set(0)))
103 .build(),
104 )
105 .child(View::styled_text(format!("count = {}", count.get())).dim().build())
106 .build(),
107 )
108 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
109 .child(
110 View::modal()
111 .visible(show_help.get())
112 .title("Example 37: Error Boundary")
113 .on_dismiss(with!(show_help => move || show_help.set(false)))
114 .child(
115 View::vstack()
116 .child(View::styled_text("What you're seeing").bold().build())
117 .child(View::text("• A counter that panics at 5"))
118 .child(View::text("• Error boundary catches the panic"))
119 .child(View::text("• Red fallback replaces the crash"))
120 .child(View::gap(1))
121 .child(View::styled_text("Key concepts").bold().build())
122 .child(View::text("• View::error_boundary()"))
123 .child(View::text("• .child(risky) .fallback(safe)"))
124 .child(View::text("• Panics are caught, not propagated"))
125 .child(View::text("• App keeps running after panic"))
126 .child(View::gap(1))
127 .child(View::styled_text("Try this").bold().build())
128 .child(View::text("• Increment to 5 to trigger panic"))
129 .child(View::text("• Reset to 0 to recover"))
130 .child(View::text("• Keep incrementing past 5"))
131 .child(View::gap(1))
132 .child(View::styled_text("Next up").bold().build())
133 .child(View::text("-> 38_custom_widget: Game of Life"))
134 .child(View::gap(1))
135 .child(View::styled_text("Press Escape to close").dim().build())
136 .build(),
137 )
138 .build(),
139 )
140 .build()
141 }Sourcepub fn build(self) -> View
pub fn build(self) -> View
Examples found in repository?
examples/37_error_boundary.rs (line 73)
38 fn render(&self, cx: Scope) -> View {
39 let show_help = state!(cx, || false);
40
41 cx.use_command(
42 KeyBinding::key(KeyCode::F(1)),
43 with!(show_help => move || show_help.update(|v| *v = !*v)),
44 );
45
46 let count = state!(cx, || 0i32);
47
48 // The panic must happen at render time (inside render_view) so the
49 // error boundary's catch_unwind can catch it. A custom widget defers
50 // execution to the render pass.
51 let risky_view = View::custom(std::rc::Rc::new(std::cell::RefCell::new(RiskyCounter(count.get()))));
52
53 let fallback = View::vstack()
54 .child(View::styled_text("CAUGHT PANIC").color(Color::Red).bold().build())
55 .child(View::text("The child view panicked."))
56 .child(View::text("But the app is still running!"))
57 .build();
58
59 View::vstack()
60 .spacing(1)
61 .child(View::styled_text("Error Boundary Demo").bold().build())
62 .child(
63 View::hstack()
64 .spacing(2)
65 .child(
66 View::vstack()
67 .spacing(1)
68 .child(View::styled_text("Protected Panel").bold().build())
69 .child(
70 View::error_boundary()
71 .child(risky_view)
72 .fallback(fallback)
73 .build(),
74 )
75 .build(),
76 )
77 .child(
78 View::vstack()
79 .spacing(1)
80 .child(View::styled_text("How It Works").bold().build())
81 .child(View::text("The left panel asserts"))
82 .child(View::text("count < 5. When it hits"))
83 .child(View::text("5, the error boundary"))
84 .child(View::text("catches the panic and"))
85 .child(View::text("renders the fallback."))
86 .build(),
87 )
88 .build(),
89 )
90 .child(
91 View::hstack()
92 .spacing(1)
93 .child(
94 View::button()
95 .label("[ + Increment ]")
96 .on_press(with!(count => move || count.update(|n| *n += 1)))
97 .build(),
98 )
99 .child(
100 View::button()
101 .label("[ Reset to 0 ]")
102 .on_press(with!(count => move || count.set(0)))
103 .build(),
104 )
105 .child(View::styled_text(format!("count = {}", count.get())).dim().build())
106 .build(),
107 )
108 .child(View::styled_text("F1 help • Ctrl+Q quit").dim().build())
109 .child(
110 View::modal()
111 .visible(show_help.get())
112 .title("Example 37: Error Boundary")
113 .on_dismiss(with!(show_help => move || show_help.set(false)))
114 .child(
115 View::vstack()
116 .child(View::styled_text("What you're seeing").bold().build())
117 .child(View::text("• A counter that panics at 5"))
118 .child(View::text("• Error boundary catches the panic"))
119 .child(View::text("• Red fallback replaces the crash"))
120 .child(View::gap(1))
121 .child(View::styled_text("Key concepts").bold().build())
122 .child(View::text("• View::error_boundary()"))
123 .child(View::text("• .child(risky) .fallback(safe)"))
124 .child(View::text("• Panics are caught, not propagated"))
125 .child(View::text("• App keeps running after panic"))
126 .child(View::gap(1))
127 .child(View::styled_text("Try this").bold().build())
128 .child(View::text("• Increment to 5 to trigger panic"))
129 .child(View::text("• Reset to 0 to recover"))
130 .child(View::text("• Keep incrementing past 5"))
131 .child(View::gap(1))
132 .child(View::styled_text("Next up").bold().build())
133 .child(View::text("-> 38_custom_widget: Game of Life"))
134 .child(View::gap(1))
135 .child(View::styled_text("Press Escape to close").dim().build())
136 .build(),
137 )
138 .build(),
139 )
140 .build()
141 }Trait Implementations§
Source§impl Default for ErrorBoundaryBuilder
impl Default for ErrorBoundaryBuilder
Source§fn default() -> ErrorBoundaryBuilder
fn default() -> ErrorBoundaryBuilder
Returns the “default value” for a type. Read more
Auto Trait Implementations§
impl Freeze for ErrorBoundaryBuilder
impl !RefUnwindSafe for ErrorBoundaryBuilder
impl !Send for ErrorBoundaryBuilder
impl !Sync for ErrorBoundaryBuilder
impl Unpin for ErrorBoundaryBuilder
impl !UnwindSafe for ErrorBoundaryBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Convert
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Convert
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Convert
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
Convert
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.