-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathlib.rs
76 lines (72 loc) · 2.31 KB
/
lib.rs
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
#![no_std]
#![feature(generators)]
use {
core::cell::UnsafeCell,
embrio::io::{self, BufReader, Read, Write},
embrio_async::embrio_async,
pin_utils::pin_mut,
};
#[derive(Debug)]
pub struct Error;
#[embrio_async]
async fn run(input: impl Read, output: impl Write) -> Result<(), Error> {
pin_mut!(output);
let input = BufReader::new(input, [0; 32]);
pin_mut!(input);
let mut buffer = [0; 64];
loop {
io::write_all(output.as_mut(), "Hello, what's your name?\n> ")
.await
.map_err(|_| Error)?;
io::flush(output.as_mut()).await.map_err(|_| Error)?;
match io::read_until(input.as_mut(), b'\n', &mut buffer[..])
.await
.map_err(|_| Error)?
{
Ok(amount) => {
if amount == 0 {
io::write_all(output.as_mut(), b"\n")
.await
.map_err(|_| Error)?;
return Ok(());
}
io::write_all(output.as_mut(), "Hi ")
.await
.map_err(|_| Error)?;
io::write_all(output.as_mut(), &buffer[..(amount - 1)])
.await
.map_err(|_| Error)?;
io::write_all(output.as_mut(), " 👋 \n\n")
.await
.map_err(|_| Error)?;
}
Err(_) => {
io::write_all(
output.as_mut(),
"\nSorry, that's a bit long for me 😭\n\n",
)
.await
.map_err(|_| Error)?;
}
}
}
}
/// # Safety
///
/// This function can only be called _once_ in the entire lifetime of a process.
pub unsafe fn main(input: impl Read, output: impl Write) -> Result<(), Error> {
struct RacyCell<T>(UnsafeCell<T>);
impl<T> RacyCell<T> {
const fn new(value: T) -> Self {
RacyCell(UnsafeCell::new(value))
}
#[allow(clippy::mut_from_ref)]
unsafe fn get_mut_unchecked(&self) -> &mut T {
&mut *self.0.get()
}
}
unsafe impl<T> Sync for RacyCell<T> {}
static EXECUTOR: RacyCell<embrio::Executor> =
RacyCell::new(embrio::Executor::new());
EXECUTOR.get_mut_unchecked().block_on(run(input, output))
}