const_format_proc_macros/
utils.rs

1use proc_macro2::Span;
2
3#[cfg(feature = "derive")]
4use quote::ToTokens;
5
6use std::{
7    collections::VecDeque,
8    iter::Fuse,
9    mem,
10    ops::{Deref, DerefMut},
11};
12
13pub(crate) fn dummy_ident() -> proc_macro2::Ident {
14    proc_macro2::Ident::new("__dummy__", Span::mixed_site())
15}
16
17////////////////////////////////////////////////////////////////////////////////////
18
19#[cfg(feature = "derive")]
20pub fn spanned_err(tokens: &dyn ToTokens, display: &dyn std::fmt::Display) -> crate::Error {
21    use syn::spanned::Spanned;
22    crate::Error::new(tokens.span(), display)
23}
24
25////////////////////////////////////////////////////////////////////////////////////
26
27#[derive(Clone, Debug)]
28pub struct Peekable2<I: Iterator> {
29    iter: Fuse<I>,
30    queue: VecDeque<I::Item>,
31}
32
33impl Peekable2<std::ops::Range<u8>> {
34    #[allow(clippy::new_ret_no_self)]
35    pub fn new<I: IntoIterator>(iter: I) -> Peekable2<I::IntoIter> {
36        Peekable2 {
37            iter: iter.into_iter().fuse(),
38            queue: VecDeque::new(),
39        }
40    }
41}
42
43impl<I: Iterator> Peekable2<I> {
44    pub fn is_empty(&mut self) -> bool {
45        self.peek().is_none()
46    }
47
48    pub fn peek(&mut self) -> Option<&I::Item> {
49        if self.queue.is_empty() {
50            self.queue.push_back(self.iter.next()?);
51        }
52        Some(&self.queue[0])
53    }
54    pub fn peek2(&mut self) -> Option<&I::Item> {
55        while self.queue.len() < 2 {
56            self.queue.push_back(self.iter.next()?);
57        }
58        Some(&self.queue[1])
59    }
60}
61
62impl<I> Iterator for Peekable2<I>
63where
64    I: Iterator,
65{
66    type Item = I::Item;
67
68    fn next(&mut self) -> Option<I::Item> {
69        if let opt @ Some(_) = self.queue.pop_front() {
70            opt
71        } else {
72            self.iter.next()
73        }
74    }
75
76    fn size_hint(&self) -> (usize, Option<usize>) {
77        let (low, high) = self.iter.size_hint();
78        let len = self.queue.len();
79        (low + len, high.map(|x| x.saturating_add(len)))
80    }
81}
82
83////////////////////////////////////////////////////////////////////////////////////
84
85/// A result wrapper which panics if it's the error variant is not handled,
86/// by calling `.into_result()`.
87#[derive(Debug, Clone)]
88pub struct LinearResult {
89    errors: Result<(), crate::Error>,
90}
91
92impl Drop for LinearResult {
93    fn drop(&mut self) {
94        mem::replace(&mut self.errors, Ok(())).expect("Expected LinearResult to be handled");
95    }
96}
97
98impl LinearResult {
99    #[inline]
100    pub fn new(res: Result<(), crate::Error>) -> Self {
101        Self { errors: res }
102    }
103
104    #[inline]
105    pub fn ok() -> Self {
106        Self::new(Ok(()))
107    }
108}
109
110impl From<Result<(), crate::Error>> for LinearResult {
111    #[inline]
112    fn from(res: Result<(), crate::Error>) -> Self {
113        Self::new(res)
114    }
115}
116
117impl Deref for LinearResult {
118    type Target = Result<(), crate::Error>;
119
120    fn deref(&self) -> &Result<(), crate::Error> {
121        &self.errors
122    }
123}
124
125impl DerefMut for LinearResult {
126    fn deref_mut(&mut self) -> &mut Result<(), crate::Error> {
127        &mut self.errors
128    }
129}
130
131#[allow(dead_code)]
132impl LinearResult {
133    #[inline]
134    pub fn into_result(mut self) -> Result<(), crate::Error> {
135        mem::replace(&mut self.errors, Ok(()))
136    }
137
138    #[inline]
139    pub fn take(&mut self) -> Result<(), crate::Error> {
140        self.replace(Ok(()))
141    }
142
143    #[inline]
144    pub fn replace(&mut self, other: Result<(), crate::Error>) -> Result<(), crate::Error> {
145        mem::replace(&mut self.errors, other)
146    }
147
148    #[inline]
149    pub fn push_err<E>(&mut self, err: E)
150    where
151        E: Into<crate::Error>,
152    {
153        let err = err.into();
154        match &mut self.errors {
155            this @ Ok(_) => *this = Err(err),
156            Err(e) => e.combine(err),
157        }
158    }
159
160    #[inline]
161    pub fn combine_err<E>(&mut self, res: Result<(), E>)
162    where
163        E: Into<crate::Error>,
164    {
165        if let Err(err) = res {
166            let err = err.into();
167            self.push_err(err);
168        }
169    }
170}