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
use std::ffi::CString;
use std::os::raw::{c_char, c_int, c_void};
use crate::host::Host;
use crate::AsRawPtr;
#[derive(Debug)]
pub struct Prompt {
pub value: String,
pub color: Option<i32>,
}
impl Prompt {
pub fn builder() -> PromptBuilder {
Default::default()
}
}
#[derive(Debug, Default)]
pub struct PromptBuilder {
x: Option<u32>,
y: Option<u32>,
with_color: bool,
}
impl PromptBuilder {
pub fn with_x(mut self, x: u32) -> Self {
self.x = Some(x);
self
}
pub fn with_y(mut self, y: u32) -> Self {
self.y = Some(y);
self
}
pub fn with_color(mut self) -> Self {
self.with_color = true;
self
}
pub fn show(self, host: &mut Host, message: String) -> Option<Prompt> {
let mut color = self.with_color as c_int - 1;
let value = CString::default().into_raw();
if unsafe {
!prompt_show(
*host.host_ptr.get_mut(),
self.x.map(|v| v as c_int).unwrap_or(-1),
self.y.map(|v| v as c_int).unwrap_or(-1),
message.as_raw_ptr() as *mut c_char,
value,
&mut color,
)
} {
unsafe { CString::from_raw(value) };
return None;
}
Some(Prompt {
value: self.value_from_raw(value),
color: self.color_to_result(color),
})
}
fn value_from_raw(&self, ptr: *mut c_char) -> String {
unsafe { CString::from_raw(ptr) }
.to_string_lossy()
.to_string()
}
fn color_to_result(&self, color: c_int) -> Option<i32> {
if self.with_color {
Some(i32::from_be(color))
} else {
None
}
}
}
extern "C" {
fn prompt_show(
host: *mut c_void,
x: c_int,
y: c_int,
msg: *mut c_char,
result: *mut c_char,
color: &mut c_int,
) -> bool;
}