@@ -141,6 +141,76 @@ where
141
141
}
142
142
}
143
143
144
+ /// A comparison of two strings.
145
+ ///
146
+ /// In contrast to [`Comparison`], which uses the [`core::fmt::Debug`] representation,
147
+ /// `StrComparison` uses the string values directly, resulting in multi-line output for multiline strings.
148
+ ///
149
+ /// ```
150
+ /// use pretty_assertions::StrComparison;
151
+ ///
152
+ /// print!("{}", StrComparison::new("foo\nbar", "foo\nbaz"));
153
+ /// ```
154
+ ///
155
+ /// ## Value type bounds
156
+ ///
157
+ /// Any value that can be referenced as a [`str`] via [`AsRef`] may be used:
158
+ ///
159
+ /// ```
160
+ /// use pretty_assertions::StrComparison;
161
+ ///
162
+ /// #[derive(PartialEq)]
163
+ /// struct MyString(String);
164
+ ///
165
+ /// impl AsRef<str> for MyString {
166
+ /// fn as_ref(&self) -> &str {
167
+ /// &self.0
168
+ /// }
169
+ /// }
170
+ ///
171
+ /// print!(
172
+ /// "{}",
173
+ /// StrComparison::new(
174
+ /// &MyString("foo\nbar".to_owned()),
175
+ /// &MyString("foo\nbaz".to_owned()),
176
+ /// ),
177
+ /// );
178
+ /// ```
179
+ ///
180
+ /// The values may have different types, although in practice they are usually the same.
181
+ pub struct StrComparison < ' a , TLeft , TRight >
182
+ where
183
+ TLeft : ?Sized ,
184
+ TRight : ?Sized ,
185
+ {
186
+ left : & ' a TLeft ,
187
+ right : & ' a TRight ,
188
+ }
189
+
190
+ impl < ' a , TLeft , TRight > StrComparison < ' a , TLeft , TRight >
191
+ where
192
+ TLeft : AsRef < str > + ?Sized ,
193
+ TRight : AsRef < str > + ?Sized ,
194
+ {
195
+ /// Store two values to be compared in future.
196
+ ///
197
+ /// Expensive diffing is deferred until calling `Debug::fmt`.
198
+ pub fn new ( left : & ' a TLeft , right : & ' a TRight ) -> StrComparison < ' a , TLeft , TRight > {
199
+ StrComparison { left, right }
200
+ }
201
+ }
202
+
203
+ impl < ' a , TLeft , TRight > Display for StrComparison < ' a , TLeft , TRight >
204
+ where
205
+ TLeft : AsRef < str > + ?Sized ,
206
+ TRight : AsRef < str > + ?Sized ,
207
+ {
208
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
209
+ printer:: write_header ( f) ?;
210
+ printer:: write_lines ( f, self . left . as_ref ( ) , self . right . as_ref ( ) )
211
+ }
212
+ }
213
+
144
214
/// Asserts that two expressions are equal to each other (using [`PartialEq`]).
145
215
///
146
216
/// On panic, this macro will print a diff derived from [`Debug`] representation of
@@ -186,6 +256,51 @@ macro_rules! assert_eq {
186
256
} ) ;
187
257
}
188
258
259
+ /// Asserts that two expressions are equal to each other (using [`PartialEq`]).
260
+ ///
261
+ /// On panic, this macro will print a diff derived from each value's [`str`] representation.
262
+ /// See [`StrComparison`] for further details.
263
+ ///
264
+ /// This is a drop in replacement for [`core::assert_eq!`].
265
+ /// You can provide a custom panic message if desired.
266
+ ///
267
+ /// # Examples
268
+ ///
269
+ /// ```
270
+ /// use pretty_assertions::assert_str_eq;
271
+ ///
272
+ /// let a = "foo\nbar";
273
+ /// let b = ["foo", "bar"].join("\n");
274
+ /// assert_str_eq!(a, b);
275
+ ///
276
+ /// assert_str_eq!(a, b, "we are testing concatenation with {} and {}", a, b);
277
+ /// ```
278
+ #[ macro_export]
279
+ macro_rules! assert_str_eq {
280
+ ( $left: expr, $right: expr$( , ) ?) => ( {
281
+ $crate:: assert_str_eq!( @ $left, $right, "" , "" ) ;
282
+ } ) ;
283
+ ( $left: expr, $right: expr, $( $arg: tt) * ) => ( {
284
+ $crate:: assert_str_eq!( @ $left, $right, ": " , $( $arg) +) ;
285
+ } ) ;
286
+ ( @ $left: expr, $right: expr, $maybe_semicolon: expr, $( $arg: tt) * ) => ( {
287
+ match ( & ( $left) , & ( $right) ) {
288
+ ( left_val, right_val) => {
289
+ if !( * left_val == * right_val) {
290
+ :: core:: panic!( "assertion failed: `(left == right)`{}{}\
291
+ \n \
292
+ \n {}\
293
+ \n ",
294
+ $maybe_semicolon,
295
+ format_args!( $( $arg) * ) ,
296
+ $crate:: StrComparison :: new( left_val, right_val)
297
+ )
298
+ }
299
+ }
300
+ }
301
+ } ) ;
302
+ }
303
+
189
304
/// Asserts that two expressions are not equal to each other (using [`PartialEq`]).
190
305
///
191
306
/// On panic, this macro will print the values of the expressions with their
0 commit comments