1
//! Misc helper functions and types for use in parsing network documents
2

            
3
use derive_deftly::define_derive_deftly;
4

            
5
pub(crate) mod str;
6

            
7
pub mod batching_split_before;
8

            
9
use std::iter::Peekable;
10

            
11
define_derive_deftly! {
12
    /// Implement `AsMut<Self>`
13
    ///
14
    /// For Reasons, Rust does not have a blanket:
15
    ///
16
    /// ```rust,ignore
17
    /// impl<T> AsMut<T> for T { .. }
18
    /// ```
19
    ///
20
    /// This derive macro expands to the obvious and trivial implementation,
21
    /// for the type that it's applied to.
22
    //
23
    // TODO move this somewhere lower in the stack, eg tor-basic-utils
24
    export AsMutSelf expect items:
25

            
26
    impl<$tgens> ::std::convert::AsMut<Self> for $ttype where $twheres {
27
2847
        fn as_mut(&mut self) -> &mut Self {
28
            self
29
        }
30
    }
31
}
32

            
33
/// An iterator with a `.peek()` method
34
///
35
/// We make this a trait to avoid entangling all the types with `Peekable`.
36
/// Ideally we would do this with `Itertools::PeekingNext`
37
/// but that was not implemented for `&mut PeekingNext`
38
/// when we wrote this code,
39
/// and we need that because we use a lot of `&mut NetdocReader`.
40
/// <https://github.com/rust-itertools/itertools/issues/678>
41
///
42
/// TODO: As of itertools 0.11.0, `PeekingNext` _is_ implemented for
43
/// `&'a mut I where I: PeekingNext`, so we can remove this type some time.
44
///
45
/// # **UNSTABLE**
46
///
47
/// This type is UNSTABLE and not part of the semver guarantees.
48
/// You'll only see it if you ran rustdoc with `--document-private-items`.
49
// This is needed because this is a trait bound for batching_split_before.
50
#[doc(hidden)]
51
pub trait PeekableIterator: Iterator {
52
    /// Inspect the next item, if there is one
53
    fn peek(&mut self) -> Option<&Self::Item>;
54
}
55

            
56
impl<I: Iterator> PeekableIterator for Peekable<I> {
57
    fn peek(&mut self) -> Option<&Self::Item> {
58
        self.peek()
59
    }
60
}
61

            
62
impl<I: PeekableIterator> PeekableIterator for &mut I {
63
10824
    fn peek(&mut self) -> Option<&Self::Item> {
64
10824
        <I as PeekableIterator>::peek(*self)
65
10824
    }
66
}
67

            
68
/// A Private module for declaring a "sealed" trait.
69
pub(crate) mod private {
70
    /// A non-exported trait, used to prevent others from implementing a trait.
71
    ///
72
    /// For more information on this pattern, see [the Rust API
73
    /// guidelines](https://rust-lang.github.io/api-guidelines/future-proofing.html#c-sealed).
74
    #[expect(dead_code, unreachable_pub)] // TODO keep this Sealed trait in case we want it again?
75
    pub trait Sealed {}
76
}
77

            
78
#[cfg(test)]
79
#[allow(unused)]
80
fn test_as_mut_compiles() {
81
    use derive_deftly::Deftly;
82

            
83
    #[derive(Deftly)]
84
    #[derive_deftly(AsMutSelf)]
85
    struct S<T: Clone>
86
    where
87
        Option<T>: Clone,
88
    {
89
        t: T,
90
    }
91

            
92
    let _: &mut S<()> = S { t: () }.as_mut();
93
}