ferth/host.rs
1//! Host traits and implementations.
2use crate::Result;
3use crate::double::Double;
4use crate::time::DateTime;
5
6mod null;
7#[cfg(feature = "repl")]
8pub mod repl;
9#[cfg(feature = "std")]
10mod std;
11
12pub use null::NullHost;
13
14#[cfg(feature = "std")]
15pub use std::StdHost;
16
17/// System I/O.
18///
19/// Hosts must implement this trait to support the words `emit`, `key`, and `refill`.
20pub trait Io {
21 /// Read a single character (byte) from the input source.
22 ///
23 /// Returns `Ok(None)` if there is no more data to read.
24 fn key(&mut self) -> Result<Option<u8>>;
25
26 /// Output a single character (byte) to the output device.
27 fn emit(&mut self, u: u8) -> Result<()>;
28
29 /// Read a line of input into `buf`.
30 ///
31 /// Returns `Ok(None)` if there is no more data to read.
32 fn refill(&mut self, buf: &mut [u8]) -> Result<Option<usize>>;
33}
34
35/// System clock.
36///
37/// Hosts must implement this trait to support the words `ms`, `time&date`, and `(utime)`.
38pub trait Clock {
39 /// Return the value of a monotonic clock, in microseconds.
40 fn utime(&self) -> Double;
41
42 /// The current time and date, in UTC.
43 fn time_and_date(&self) -> DateTime;
44
45 /// Sleep for *ms* milliseconds.
46 fn sleep_ms(&self, ms: usize);
47}
48
49/// A proxy for `Clock` that requires it only when the build includes clock builtins.
50///
51/// `Kernel` and `Fe` can reference this trait instead of `Clock`. This avoids having to duplicate
52/// functions for each combination of traits (`H: Io`, `H: Io + Clock`).
53///
54/// Do not implement this trait directly. It is implemented automatically for any type that
55/// implements `Clock`.
56#[cfg(not(feature = "std"))]
57pub trait MaybeClock {}
58#[cfg(not(feature = "std"))]
59impl<T> MaybeClock for T {}
60
61#[cfg(feature = "std")]
62pub trait MaybeClock: Clock {}
63#[cfg(feature = "std")]
64impl<T: Clock> MaybeClock for T {}