1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
//! Misc helper functions and types for use in parsing network documents
use derive_deftly::define_derive_deftly;
pub(crate) mod str;
pub mod batching_split_before;
use std::iter::Peekable;
#[cfg(test)]
use std::fmt::Display;
define_derive_deftly! {
/// Implement `AsMut<Self>`
///
/// For Reasons, Rust does not have a blanket:
///
/// ```rust,ignore
/// impl<T> AsMut<T> for T { .. }
/// ```
///
/// This derive macro expands to the obvious and trivial implementation,
/// for the type that it's applied to.
//
// TODO move this somewhere lower in the stack, eg tor-basic-utils
export AsMutSelf expect items:
impl<$tgens> ::std::convert::AsMut<Self> for $ttype where $twheres {
fn as_mut(&mut self) -> &mut Self {
self
}
}
}
#[cfg(test)]
/// Assert that `$a = $b`; if not, panic with a unidiff
//
// implementation is in fn assert_eq_or_diff, at the bottom of the file
macro_rules! assert_eq_or_diff {
{ $a:expr, $b:expr $(,)? } => {
assert_eq_or_diff!($a, $b, "")
};
{ $a:expr, $b:expr , $($message:tt)*} => {
$crate::util::assert_eq_or_diff(
&$a,
stringify!($a),
&$b,
stringify!($b),
&format_args!($($message)*),
)
};
}
/// An iterator with a `.peek()` method
///
/// We make this a trait to avoid entangling all the types with `Peekable`.
/// Ideally we would do this with `Itertools::PeekingNext`
/// but that was not implemented for `&mut PeekingNext`
/// when we wrote this code,
/// and we need that because we use a lot of `&mut NetdocReader`.
/// <https://github.com/rust-itertools/itertools/issues/678>
///
/// TODO: As of itertools 0.11.0, `PeekingNext` _is_ implemented for
/// `&'a mut I where I: PeekingNext`, so we can remove this type some time.
///
/// # **UNSTABLE**
///
/// This type is UNSTABLE and not part of the semver guarantees.
/// You'll only see it if you ran rustdoc with `--document-private-items`.
// This is needed because this is a trait bound for batching_split_before.
#[doc(hidden)]
pub trait PeekableIterator: Iterator {
/// Inspect the next item, if there is one
fn peek(&mut self) -> Option<&Self::Item>;
}
impl<I: Iterator> PeekableIterator for Peekable<I> {
fn peek(&mut self) -> Option<&Self::Item> {
self.peek()
}
}
impl<I: PeekableIterator> PeekableIterator for &mut I {
fn peek(&mut self) -> Option<&Self::Item> {
<I as PeekableIterator>::peek(*self)
}
}
/// A Private module for declaring a "sealed" trait.
pub(crate) mod private {
/// A non-exported trait, used to prevent others from implementing a trait.
///
/// For more information on this pattern, see [the Rust API
/// guidelines](https://rust-lang.github.io/api-guidelines/future-proofing.html#c-sealed).
#[expect(dead_code, unreachable_pub)] // TODO keep this Sealed trait in case we want it again?
pub trait Sealed {}
}
#[cfg(test)]
#[allow(unused)]
fn test_as_mut_compiles() {
use derive_deftly::Deftly;
#[derive(Deftly)]
#[derive_deftly(AsMutSelf)]
struct S<T: Clone>
where
Option<T>: Clone,
{
t: T,
}
let _: &mut S<()> = S { t: () }.as_mut();
}
#[cfg(test)]
pub(crate) fn regsub(update: &mut String, re: &str, repl: impl regex::Replacer) {
*update = regex::Regex::new(&format!("(?m){re}"))
.expect(re)
.replace_all(update, repl)
.to_string();
}
#[cfg(test)]
pub(crate) fn assert_eq_or_diff(
a: &str,
a_what: &str,
b: &str,
b_what: &str,
message: &dyn Display,
) {
use imara_diff::{Algorithm, BasicLineDiffPrinter, Diff, InternedInput, UnifiedDiffConfig};
if a == b {
return;
}
let input = InternedInput::new(a, b);
let mut diff = Diff::compute(Algorithm::Histogram, &input);
diff.postprocess_lines(&input);
panic!(
// rustdoc insists on this unhelpful formatting
"===== document {a_what} =====
{a}
===== document {b_what} =====
{b}
===== diff ====
{}
===== documents differ: {a_what} != {b_what} =====
{message}
",
diff.unified_diff(
&BasicLineDiffPrinter(&input.interner),
UnifiedDiffConfig::default(),
&input,
),
);
}
|