]> git.proxmox.com Git - rustc.git/blame - vendor/anyhow/tests/test_context.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / vendor / anyhow / tests / test_context.rs
CommitLineData
136023e0
XL
1#![allow(
2 // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
3 clippy::nonstandard_macro_braces,
4)]
5
dfeec247
XL
6mod drop;
7
8use crate::drop::{DetectDrop, Flag};
9use anyhow::{Context, Error, Result};
10use std::fmt::{self, Display};
11use thiserror::Error;
12
13// https://github.com/dtolnay/anyhow/issues/18
14#[test]
15fn test_inference() -> Result<()> {
16 let x = "1";
17 let y: u32 = x.parse().context("...")?;
18 assert_eq!(y, 1);
19 Ok(())
20}
21
22macro_rules! context_type {
23 ($name:ident) => {
24 #[derive(Debug)]
25 struct $name {
26 message: &'static str,
27 drop: DetectDrop,
28 }
29
30 impl Display for $name {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 f.write_str(self.message)
33 }
34 }
35 };
36}
37
38context_type!(HighLevel);
39context_type!(MidLevel);
40
41#[derive(Error, Debug)]
42#[error("{message}")]
43struct LowLevel {
44 message: &'static str,
45 drop: DetectDrop,
46}
47
48struct Dropped {
49 low: Flag,
50 mid: Flag,
51 high: Flag,
52}
53
54impl Dropped {
55 fn none(&self) -> bool {
56 !self.low.get() && !self.mid.get() && !self.high.get()
57 }
58
59 fn all(&self) -> bool {
60 self.low.get() && self.mid.get() && self.high.get()
61 }
62}
63
64fn make_chain() -> (Error, Dropped) {
65 let dropped = Dropped {
66 low: Flag::new(),
67 mid: Flag::new(),
68 high: Flag::new(),
69 };
70
71 let low = LowLevel {
72 message: "no such file or directory",
73 drop: DetectDrop::new(&dropped.low),
74 };
75
76 // impl Context for Result<T, E>
77 let mid = Err::<(), LowLevel>(low)
78 .context(MidLevel {
79 message: "failed to load config",
80 drop: DetectDrop::new(&dropped.mid),
81 })
82 .unwrap_err();
83
84 // impl Context for Result<T, Error>
85 let high = Err::<(), Error>(mid)
86 .context(HighLevel {
87 message: "failed to start server",
88 drop: DetectDrop::new(&dropped.high),
89 })
90 .unwrap_err();
91
92 (high, dropped)
93}
94
95#[test]
96fn test_downcast_ref() {
97 let (err, dropped) = make_chain();
98
99 assert!(!err.is::<String>());
100 assert!(err.downcast_ref::<String>().is_none());
101
102 assert!(err.is::<HighLevel>());
103 let high = err.downcast_ref::<HighLevel>().unwrap();
104 assert_eq!(high.to_string(), "failed to start server");
105
106 assert!(err.is::<MidLevel>());
107 let mid = err.downcast_ref::<MidLevel>().unwrap();
108 assert_eq!(mid.to_string(), "failed to load config");
109
110 assert!(err.is::<LowLevel>());
111 let low = err.downcast_ref::<LowLevel>().unwrap();
112 assert_eq!(low.to_string(), "no such file or directory");
113
114 assert!(dropped.none());
115 drop(err);
116 assert!(dropped.all());
117}
118
119#[test]
120fn test_downcast_high() {
121 let (err, dropped) = make_chain();
122
123 let err = err.downcast::<HighLevel>().unwrap();
124 assert!(!dropped.high.get());
125 assert!(dropped.low.get() && dropped.mid.get());
126
127 drop(err);
128 assert!(dropped.all());
129}
130
131#[test]
132fn test_downcast_mid() {
133 let (err, dropped) = make_chain();
134
135 let err = err.downcast::<MidLevel>().unwrap();
136 assert!(!dropped.mid.get());
137 assert!(dropped.low.get() && dropped.high.get());
138
139 drop(err);
140 assert!(dropped.all());
141}
142
143#[test]
144fn test_downcast_low() {
145 let (err, dropped) = make_chain();
146
147 let err = err.downcast::<LowLevel>().unwrap();
148 assert!(!dropped.low.get());
149 assert!(dropped.mid.get() && dropped.high.get());
150
151 drop(err);
152 assert!(dropped.all());
153}
154
155#[test]
156fn test_unsuccessful_downcast() {
157 let (err, dropped) = make_chain();
158
159 let err = err.downcast::<String>().unwrap_err();
160 assert!(dropped.none());
161
162 drop(err);
163 assert!(dropped.all());
164}
136023e0
XL
165
166#[test]
167fn test_root_cause() {
168 let (err, _) = make_chain();
169
170 assert_eq!(err.root_cause().to_string(), "no such file or directory");
171}