/rust/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.98/src/chain.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use self::ChainState::*; |
2 | | use crate::StdError; |
3 | | |
4 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
5 | | use alloc::vec::{self, Vec}; |
6 | | |
7 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
8 | | pub(crate) use crate::Chain; |
9 | | |
10 | | #[cfg(all(not(feature = "std"), anyhow_no_core_error))] |
11 | | pub(crate) struct Chain<'a> { |
12 | | state: ChainState<'a>, |
13 | | } |
14 | | |
15 | | #[derive(Clone)] |
16 | | pub(crate) enum ChainState<'a> { |
17 | | Linked { |
18 | | next: Option<&'a (dyn StdError + 'static)>, |
19 | | }, |
20 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
21 | | Buffered { |
22 | | rest: vec::IntoIter<&'a (dyn StdError + 'static)>, |
23 | | }, |
24 | | } |
25 | | |
26 | | impl<'a> Chain<'a> { |
27 | | #[cold] |
28 | 0 | pub fn new(head: &'a (dyn StdError + 'static)) -> Self { |
29 | 0 | Chain { |
30 | 0 | state: ChainState::Linked { next: Some(head) }, |
31 | 0 | } |
32 | 0 | } |
33 | | } |
34 | | |
35 | | impl<'a> Iterator for Chain<'a> { |
36 | | type Item = &'a (dyn StdError + 'static); |
37 | | |
38 | 0 | fn next(&mut self) -> Option<Self::Item> { |
39 | 0 | match &mut self.state { |
40 | 0 | Linked { next } => { |
41 | 0 | let error = (*next)?; |
42 | 0 | *next = error.source(); |
43 | 0 | Some(error) |
44 | | } |
45 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
46 | 0 | Buffered { rest } => rest.next(), |
47 | | } |
48 | 0 | } |
49 | | |
50 | 0 | fn size_hint(&self) -> (usize, Option<usize>) { |
51 | 0 | let len = self.len(); |
52 | 0 | (len, Some(len)) |
53 | 0 | } |
54 | | } |
55 | | |
56 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
57 | | impl DoubleEndedIterator for Chain<'_> { |
58 | 0 | fn next_back(&mut self) -> Option<Self::Item> { |
59 | 0 | match &mut self.state { |
60 | 0 | Linked { mut next } => { |
61 | 0 | let mut rest = Vec::new(); |
62 | 0 | while let Some(cause) = next { |
63 | 0 | next = cause.source(); |
64 | 0 | rest.push(cause); |
65 | 0 | } |
66 | 0 | let mut rest = rest.into_iter(); |
67 | 0 | let last = rest.next_back(); |
68 | 0 | self.state = Buffered { rest }; |
69 | 0 | last |
70 | | } |
71 | 0 | Buffered { rest } => rest.next_back(), |
72 | | } |
73 | 0 | } |
74 | | } |
75 | | |
76 | | impl ExactSizeIterator for Chain<'_> { |
77 | 0 | fn len(&self) -> usize { |
78 | 0 | match &self.state { |
79 | 0 | Linked { mut next } => { |
80 | 0 | let mut len = 0; |
81 | 0 | while let Some(cause) = next { |
82 | 0 | next = cause.source(); |
83 | 0 | len += 1; |
84 | 0 | } |
85 | 0 | len |
86 | | } |
87 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
88 | 0 | Buffered { rest } => rest.len(), |
89 | | } |
90 | 0 | } |
91 | | } |
92 | | |
93 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
94 | | impl Default for Chain<'_> { |
95 | 0 | fn default() -> Self { |
96 | 0 | Chain { |
97 | 0 | state: ChainState::Buffered { |
98 | 0 | rest: Vec::new().into_iter(), |
99 | 0 | }, |
100 | 0 | } |
101 | 0 | } |
102 | | } |