1pub trait OrThrow<T> {
3 fn or_throw<E: crate::Exn>(self, exn: E) -> T;
5}
6
7impl<T, Err> OrThrow<T> for Result<T, Err> {
8 #[cfg_attr(not(target_arch = "riscv32"), track_caller)]
9 fn or_throw<E: crate::Exn>(self, exn: E) -> T {
10 match self {
11 Ok(v) => v,
12 Err(_) => throw(exn),
13 }
14 }
15}
16
17impl<T> OrThrow<T> for Option<T> {
18 #[cfg_attr(not(target_arch = "riscv32"), track_caller)]
19 fn or_throw<E: crate::Exn>(self, exn: E) -> T {
20 match self {
21 Some(v) => v,
22 None => throw(exn),
23 }
24 }
25}
26
27#[cfg_attr(not(target_arch = "riscv32"), track_caller)]
28pub fn throw<E>(exn: E) -> !
29where
30 E: crate::Exn,
31{
32 let exn = crate::exn::cross_exn::ContractExn::new(exn);
33 crate::contract_abort_encoded(&exn)
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 use crate::exn::Exn;
40 use crate::xdr::*;
41
42 #[derive(Debug, Clone, PartialEq, ReadXDR, WriteXDR)]
43 #[repr(i32)]
44 enum TestExn {
45 Boom = 1,
46 }
47 impl Exn for TestExn {
48 const SELECTOR: u64 = 0xDEAD;
49 }
50
51 #[test]
52 fn or_throw_ok_returns_value() {
53 let result: Result<i32, &str> = Ok(42);
54 assert_eq!(result.or_throw(TestExn::Boom), 42);
55 }
56}