1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use crate::{backend, backends, Cursive};
type Initializer =
dyn FnMut()
-> Result<Box<dyn backend::Backend>, Box<dyn std::error::Error>>;
pub struct CursiveRunnable {
siv: Cursive,
backend_init: Box<Initializer>,
}
impl std::ops::Deref for CursiveRunnable {
type Target = Cursive;
fn deref(&self) -> &Cursive {
&self.siv
}
}
impl std::ops::DerefMut for CursiveRunnable {
fn deref_mut(&mut self) -> &mut Cursive {
&mut self.siv
}
}
fn boxed(e: impl std::error::Error + 'static) -> Box<dyn std::error::Error> {
Box::new(e)
}
impl CursiveRunnable {
pub fn new<E, F>(mut backend_init: F) -> Self
where
E: std::error::Error + 'static,
F: FnMut() -> Result<Box<dyn backend::Backend>, E> + 'static,
{
let siv = Cursive::new();
let backend_init = Box::new(move || backend_init().map_err(boxed));
Self { siv, backend_init }
}
pub fn run(&mut self) {
self.try_run().unwrap();
}
pub fn try_run(&mut self) -> Result<(), Box<dyn std::error::Error>> {
self.siv.try_run_with(&mut self.backend_init)
}
pub fn dummy() -> Self {
Self::new::<std::convert::Infallible, _>(|| {
Ok(cursive_core::backend::Dummy::init())
})
}
#[cfg(feature = "ncurses-backend")]
pub fn ncurses() -> Self {
Self::new(backends::curses::n::Backend::init)
}
#[cfg(feature = "pancurses-backend")]
pub fn pancurses() -> Self {
Self::new(backends::curses::pan::Backend::init)
}
#[cfg(feature = "termion-backend")]
pub fn termion() -> Self {
Self::new(backends::termion::Backend::init)
}
#[cfg(feature = "crossterm-backend")]
pub fn crossterm() -> Self {
Self::new(backends::crossterm::Backend::init)
}
#[cfg(feature = "blt-backend")]
pub fn blt() -> Self {
Self::new::<std::convert::Infallible, _>(|| {
Ok(backends::blt::Backend::init())
})
}
pub fn default() -> Self {
cfg_if::cfg_if! {
if #[cfg(feature = "blt-backend")] {
Self::blt()
} else if #[cfg(feature = "termion-backend")] {
Self::termion()
} else if #[cfg(feature = "crossterm-backend")] {
Self::crossterm()
} else if #[cfg(feature = "pancurses-backend")] {
Self::pancurses()
} else if #[cfg(feature = "ncurses-backend")] {
Self::ncurses()
} else {
log::warn!("No built-it backend, falling back to Cursive::dummy().");
Self::dummy()
}
}
}
}