tor_netdoc/util.rs
1//! Misc helper functions and types for use in parsing network documents
2
3use derive_deftly::define_derive_deftly;
4
5pub(crate) mod rangemap_ext;
6pub(crate) mod str;
7
8pub mod batching_split_before;
9
10use std::iter::Peekable;
11
12define_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 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)]
52pub trait PeekableIterator: Iterator {
53 /// Inspect the next item, if there is one
54 fn peek(&mut self) -> Option<&Self::Item>;
55}
56
57impl<I: Iterator> PeekableIterator for Peekable<I> {
58 fn peek(&mut self) -> Option<&Self::Item> {
59 self.peek()
60 }
61}
62
63impl<I: PeekableIterator> PeekableIterator for &mut I {
64 fn peek(&mut self) -> Option<&Self::Item> {
65 <I as PeekableIterator>::peek(*self)
66 }
67}
68
69/// A Private module for declaring a "sealed" trait.
70pub(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)]
81fn 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}