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 }