Coverage Report

Created: 2025-06-02 07:01

/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
}