calc_rational

CLI calculator for rational numbers.
git clone https://git.philomathiclife.com/repos/calc_rational
Log | Files | Refs | README

main.rs (2385B)


      1 //! # `calc`
      2 //!
      3 //! Consult [`README.md`](https://crates.io/crates/calc_rational).
      4 #[cfg(feature = "std")]
      5 use calc_lib::{EvalIter, lending_iterator::LendingIterator as _};
      6 #[cfg(feature = "std")]
      7 use core::fmt::{self, Display, Formatter};
      8 #[cfg(all(feature = "priv_sep", target_os = "openbsd"))]
      9 use priv_sep::{Promise, Promises};
     10 #[cfg(feature = "std")]
     11 use std::{
     12     error,
     13     io::{self, Error, Write as _},
     14 };
     15 /// Error returned by [`main`].
     16 #[cfg(feature = "std")]
     17 #[derive(Debug)]
     18 enum Err {
     19     /// Error returned from [`writeln`].
     20     Io(Error),
     21     #[cfg(all(feature = "priv_sep", target_os = "openbsd"))]
     22     /// Error returned from `pledge`.
     23     Pledge(Error),
     24 }
     25 #[cfg(feature = "std")]
     26 impl Display for Err {
     27     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
     28         match *self {
     29             Self::Io(ref e) => e.fmt(f),
     30             #[cfg(all(feature = "priv_sep", target_os = "openbsd"))]
     31             Self::Pledge(ref e) => write!(f, "pledge(2)ing 'stdio' failed with {e}"),
     32         }
     33     }
     34 }
     35 #[cfg(feature = "std")]
     36 impl error::Error for Err {}
     37 #[cfg(not(feature = "std"))]
     38 fn main() {}
     39 /// Entry point to the calc program.
     40 ///
     41 /// # Errors
     42 ///
     43 /// Returns [`Error`] if[`writeln`] returns one when writing
     44 /// to the global standard output stream. Returns [`Error`] if
     45 /// [`pledge`](https://docs.rs/priv_sep/latest/priv_sep/fn.pledge.html)
     46 /// does when compiled with the `priv_sep` feature which
     47 /// currently only works on OpenBSD-stable.
     48 #[cfg(feature = "std")]
     49 fn main() -> Result<(), Err> {
     50     /// Calls `pledge(2)` with the "stdio" promise.
     51     #[cfg(all(feature = "priv_sep", target_os = "openbsd"))]
     52     fn privsep() -> Result<(), Err> {
     53         Promises::new([Promise::Stdio])
     54             .pledge()
     55             .map_err(Err::Pledge)
     56     }
     57     /// Returns Ok.
     58     #[expect(
     59         clippy::unnecessary_wraps,
     60         reason = "consistent return type with priv_sep feature"
     61     )]
     62     #[cfg(not(all(feature = "priv_sep", target_os = "openbsd")))]
     63     const fn privsep() -> Result<(), Err> {
     64         Ok(())
     65     }
     66     privsep().and_then(|()| {
     67         let mut out = io::stdout().lock();
     68         EvalIter::new(io::stdin().lock()).lend_try_fold((), |(), res| {
     69             match res {
     70                 Ok(o) => writeln!(&mut out, "{o}"),
     71                 Err(e) => writeln!(&mut out, "{e}"),
     72             }
     73             .map_err(Err::Io)
     74         })
     75     })
     76 }