Macro konst::try_ [−][src]
macro_rules! try_ { ($e : expr, map_err = | $($pati : pat) ? | $v : expr $(,) *) => { ... }; ($e : expr $(,) *) => { ... }; }
Expand description
?
-like macro, which allows optionally mapping errors.
?
currently doesn’t work in const fn
s because as of Rust 1.51.0
trait methods don’t work in const fn
s.
Examples
Basic
use konst::try_; const OK: Result<&str, u8> = expect_no_whitespace("hello"); assert_eq!(OK, Ok("hello")); const ERR: Result<&str, u8> = expect_no_whitespace("hello world"); assert_eq!(ERR, Err(b' ')); const fn expect_no_whitespace(string: &str) -> Result<&str, u8> { let bytes = string.as_bytes(); konst::for_range!{i in 0..bytes.len() => try_!(assert_not_whitespace(bytes[i])); } Ok(string) } const fn assert_not_whitespace(byte: u8) -> Result<(), u8> { if matches!(byte, b'\t' | b'\n' | b'\r' | b' ') { Err(byte) } else { Ok(()) } }
Mapping errors
use konst::try_; const EVENS: Result<[Even; 4], u32> = array_to_even([0, 2, 4, 6]); let new = |n| Even::new(n).unwrap(); assert_eq!(EVENS, Ok([new(0), new(2), new(4), new(6)])); const UNEVEN: Result<[Even; 4], u32> = array_to_even([0, 2, 5, 6]); assert_eq!(UNEVEN, Err(5)); const fn array_to_even(arr: [u32; 4]) -> Result<[Even; 4], u32> { let mut ret = [Even::ZERO; 4]; konst::for_range!{i in 0..4 => ret[i] = try_!(Even::new(arr[i]), map_err = |e| e.get() ); } Ok(ret) } #[derive(Debug, PartialEq)] pub struct Even(u32); impl Even { const ZERO: Even = Even(0); pub const fn new(number: u32) -> Result<Self, NotEven> { if number % 2 == 0 { Ok(Even(number)) } else { Err(NotEven(number)) } } } #[derive(Debug, PartialEq)] pub struct NotEven(u32); impl NotEven { pub const fn get(&self) -> u32 { self.0 } } use std::fmt::{self, Display}; impl Display for NotEven { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(self, f) } } impl std::error::Error for NotEven {}