calc_rational

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

main.rs (2432B)


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