summaryrefslogtreecommitdiffstats
path: root/vendor/anyhow/src/chain.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/anyhow/src/chain.rs')
-rw-r--r--vendor/anyhow/src/chain.rs102
1 files changed, 102 insertions, 0 deletions
diff --git a/vendor/anyhow/src/chain.rs b/vendor/anyhow/src/chain.rs
new file mode 100644
index 000000000..f7baff29f
--- /dev/null
+++ b/vendor/anyhow/src/chain.rs
@@ -0,0 +1,102 @@
+use self::ChainState::*;
+use crate::StdError;
+
+#[cfg(feature = "std")]
+use std::vec;
+
+#[cfg(feature = "std")]
+pub(crate) use crate::Chain;
+
+#[cfg(not(feature = "std"))]
+pub(crate) struct Chain<'a> {
+ state: ChainState<'a>,
+}
+
+#[derive(Clone)]
+pub(crate) enum ChainState<'a> {
+ Linked {
+ next: Option<&'a (dyn StdError + 'static)>,
+ },
+ #[cfg(feature = "std")]
+ Buffered {
+ rest: vec::IntoIter<&'a (dyn StdError + 'static)>,
+ },
+}
+
+impl<'a> Chain<'a> {
+ #[cold]
+ pub fn new(head: &'a (dyn StdError + 'static)) -> Self {
+ Chain {
+ state: ChainState::Linked { next: Some(head) },
+ }
+ }
+}
+
+impl<'a> Iterator for Chain<'a> {
+ type Item = &'a (dyn StdError + 'static);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match &mut self.state {
+ Linked { next } => {
+ let error = (*next)?;
+ *next = error.source();
+ Some(error)
+ }
+ #[cfg(feature = "std")]
+ Buffered { rest } => rest.next(),
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.len();
+ (len, Some(len))
+ }
+}
+
+#[cfg(feature = "std")]
+impl DoubleEndedIterator for Chain<'_> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ match &mut self.state {
+ Linked { mut next } => {
+ let mut rest = Vec::new();
+ while let Some(cause) = next {
+ next = cause.source();
+ rest.push(cause);
+ }
+ let mut rest = rest.into_iter();
+ let last = rest.next_back();
+ self.state = Buffered { rest };
+ last
+ }
+ Buffered { rest } => rest.next_back(),
+ }
+ }
+}
+
+impl ExactSizeIterator for Chain<'_> {
+ fn len(&self) -> usize {
+ match &self.state {
+ Linked { mut next } => {
+ let mut len = 0;
+ while let Some(cause) = next {
+ next = cause.source();
+ len += 1;
+ }
+ len
+ }
+ #[cfg(feature = "std")]
+ Buffered { rest } => rest.len(),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl Default for Chain<'_> {
+ fn default() -> Self {
+ Chain {
+ state: ChainState::Buffered {
+ rest: Vec::new().into_iter(),
+ },
+ }
+ }
+}