1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
use terrors::OneOf;
#[derive(Debug)]
struct NotEnoughMemory;
#[derive(Debug)]
struct Timeout;
#[derive(Debug)]
struct RetriesExhausted;
#[test]
fn retry() {
fn inner() -> Result<(), OneOf<(NotEnoughMemory, RetriesExhausted)>> {
for _ in 0..3 {
let Err(err) = does_stuff() else {
return Ok(());
};
match err.narrow::<Timeout, _>() {
Ok(_timeout) => continue,
Err(allocation_oneof) => {
println!("didn't get Timeout, now trying to get NotEnoughMemory");
let allocation_oneof: OneOf<(NotEnoughMemory,)> = allocation_oneof;
let allocation = allocation_oneof.narrow::<NotEnoughMemory, _>().unwrap();
return Err(OneOf::new(allocation));
}
}
}
Err(OneOf::new(RetriesExhausted))
}
let _ = dbg!(inner());
}
fn does_stuff() -> Result<(), OneOf<(NotEnoughMemory, Timeout)>> {
// TODO Try impl after superset type work
let _allocation = match allocates() {
Ok(a) => a,
Err(e) => return Err(e.broaden()),
};
// TODO Try impl after superset type work
let _chat = match chats() {
Ok(c) => c,
Err(e) => return Err(OneOf::new(e)),
};
Ok(())
}
fn allocates() -> Result<(), OneOf<(NotEnoughMemory,)>> {
let result: Result<(), NotEnoughMemory> = Err(NotEnoughMemory);
result?;
Ok(())
}
fn chats() -> Result<(), Timeout> {
Err(Timeout)
}
#[test]
fn smoke() {
let o_1: OneOf<(u32, String)> = OneOf::new(5_u32);
let _narrowed_1: u32 = o_1.narrow::<u32, _>().unwrap();
let o_2: OneOf<(String, u32)> = OneOf::new(5_u32);
let _narrowed_2: u32 = o_2.narrow::<u32, _>().unwrap();
let o_3: OneOf<(String, u32)> = OneOf::new("5".to_string());
let _narrowed_3: OneOf<(String,)> = o_3.narrow::<u32, _>().unwrap_err();
let o_4: OneOf<(String, u32)> = OneOf::new("5".to_string());
let _: String = o_4.narrow().unwrap();
let o_5: OneOf<(String, u32)> = OneOf::new("5".to_string());
o_5.narrow::<String, _>().unwrap();
let o_6: OneOf<(String, u32)> = OneOf::new("5".to_string());
let o_7: OneOf<(u32, String)> = o_6.broaden();
let o_8: OneOf<(String, u32)> = o_7.subset().unwrap();
let _: OneOf<(u32, String)> = o_8.subset().unwrap();
let o_9: OneOf<(u8, u16, u32)> = OneOf::new(3_u32);
let _: Result<OneOf<(u16,)>, OneOf<(u8, u32)>> = o_9.subset();
let o_10: OneOf<(u8, u16, u32)> = OneOf::new(3_u32);
let _: Result<u16, OneOf<(u8, u32)>> = o_10.narrow();
}
#[test]
fn debug() {
use std::error::Error;
use std::io;
let o_1: OneOf<(u32, String)> = OneOf::new(5_u32);
// Debug is implemented if all types in the type set implement Debug
dbg!(&o_1);
// Display is implemented if all types in the type set implement Display
println!("{}", o_1);
type E = io::Error;
let e = io::Error::new(io::ErrorKind::Other, "wuaaaaahhhzzaaaaaaaa");
let o_2: OneOf<(E,)> = OneOf::new(e);
// std::error::Error is implemented if all types in the type set implement it
dbg!(o_2.source());
let o_3: OneOf<(u32, String)> = OneOf::new("hey".to_string());
dbg!(o_3);
}
#[test]
fn multi_match() {
use terrors::E2;
let o_1: OneOf<(u32, String)> = OneOf::new(5_u32);
match o_1.as_enum() {
E2::A(u) => {
println!("handling {u}: u32")
}
E2::B(s) => {
println!("handling {s}: String")
}
}
match o_1.to_enum() {
E2::A(u) => {
println!("handling {u}: u32")
}
E2::B(s) => {
println!("handling {s}: String")
}
}
}
#[test]
fn multi_narrow() {
use terrors::E2;
struct Timeout {}
struct Backoff {}
let o_1: OneOf<(u8, u16, u32, u64, u128)> = OneOf::new(5_u32);
let _narrow_res: Result<OneOf<(u8, u128)>, OneOf<(u16, u32, u64)>> = o_1.subset();
let o_2: OneOf<(u8, u16, Backoff, Timeout, u32, u64, u128)> = OneOf::new(Timeout {});
match o_2.subset::<(Timeout, Backoff), _>().unwrap().to_enum() {
E2::A(Timeout {}) => {
println!(":)");
}
E2::B(Backoff {}) => {
unreachable!()
}
}
}
|