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 rangemap_ext;
6
pub(crate) mod str;
7

            
8
pub mod batching_split_before;
9

            
10
use std::iter::Peekable;
11

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

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

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

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

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

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

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

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

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