1use crate::setup;
2use pretty_assertions::{assert_eq, assert_ne};
3use std::borrow::Cow;
4use std::fmt::Debug;
5use std::io::Cursor;
6use std::ops::Deref;
7
8#[track_caller]
28pub fn ref_equal<A>(a: &(impl AsRef<A> + Debug), b: &(impl AsRef<A> + Debug))
29where
30 A: Debug + PartialEq + ?Sized,
31{
32 assert_eq!(a.as_ref(), b.as_ref());
33}
34
35pub trait Unwrappable<T, R> {
38 type Output: Debug + PartialEq<R>;
39 fn unwrap_into(self) -> Self::Output;
40}
41
42impl<T: Debug + PartialEq + PartialEq<R>, R: Debug + PartialEq<T>> Unwrappable<T, R> for T {
43 type Output = T;
44 fn unwrap_into(self) -> Self::Output {
45 self
46 }
47}
48
49impl<T: Debug + PartialEq + PartialEq<R>, R: Debug + PartialEq<T>> Unwrappable<T, R> for Option<T> {
50 type Output = T;
51 fn unwrap_into(self) -> Self::Output {
52 self.unwrap() }
54}
55
56impl<T: Debug + PartialEq + PartialEq<R>, R: Debug + PartialEq<T>, E: std::fmt::Debug> Unwrappable<T, R>
57 for std::result::Result<T, E>
58{
59 type Output = T;
60 fn unwrap_into(self) -> Self::Output {
61 self.unwrap() }
63}
64
65impl<T: Debug + PartialEq + PartialEq<R>, R: Debug + PartialEq<T>, E: std::fmt::Debug> Unwrappable<T, R>
66 for std::result::Result<Option<T>, E>
67{
68 type Output = T;
69 fn unwrap_into(self) -> Self::Output {
70 self.unwrap().unwrap() }
72}
73
74impl<T: Debug + PartialEq + PartialEq<R>, R: Debug + PartialEq<T>, E: std::fmt::Debug> Unwrappable<T, R>
75 for Option<std::result::Result<T, E>>
76{
77 type Output = T;
78 fn unwrap_into(self) -> Self::Output {
79 self.unwrap().unwrap() }
81}
82
83#[track_caller]
110pub fn equal<E, T, R>(a: E, b: R)
111where
112 E: Debug + Unwrappable<T, R>,
113 E::Output: Debug + PartialEq<R>,
114 R: Debug + PartialEq + PartialEq<T>,
115{
116 let c = a.unwrap_into();
117 assert_eq!(c, b, "Expected {:?} to equal {:?}.", c, b);
118}
119
120#[track_caller]
140pub fn not_equal<A, T, B>(a: A, b: B)
141where
142 A: Debug + Unwrappable<T, B>,
143 B: Debug + PartialEq<A::Output>,
144{
145 let c = a.unwrap_into();
146 assert_ne!(c, b, "Expected {:?} to not equal {:?}.", c, b);
147}
148
149#[track_caller]
164pub fn equal_bytes<R, E>(a: &R, b: &E)
165where
166 R: AsRef<[u8]> + ?Sized,
167 E: AsRef<[u8]> + ?Sized,
168{
169 assert_eq!(
170 a.as_ref(),
171 b.as_ref(),
172 "Expected {:02x?} to equal {:02x?}.",
173 a.as_ref(),
174 b.as_ref()
175 );
176}
177
178#[track_caller]
204pub fn equal_file_contents<R>(a: &R, path: &str)
205where
206 R: AsRef<[u8]> + ?Sized,
207{
208 let expected = setup::get_file_contents(path).unwrap();
209 ref_equal(&a.as_ref(), &expected);
210}
211
212#[track_caller]
228pub fn equal_hex_bytes<R>(a: &R, b: &str)
229where
230 R: AsRef<[u8]> + ?Sized,
231{
232 let value = hex::encode(a.as_ref());
233 assert_eq!(value, b, "Expected {} to equal {}.", value, b);
234}
235
236#[track_caller]
250pub fn some<T>(a: &Option<T>)
251where
252 T: Debug,
253{
254 assert!(a.is_some(), "Expected to be some: {:?}", a);
255}
256
257#[track_caller]
272pub fn some_into<T>(a: Option<T>) -> T
273where
274 T: Debug,
275{
276 assert!(a.is_some(), "Expected to be some: {:?}", a);
277 a.unwrap()
278}
279
280#[track_caller]
294pub fn none<T>(a: &Option<T>)
295where
296 T: Debug,
297{
298 assert!(a.is_none(), "Expected to be none: {:?}", a);
299}
300
301#[track_caller]
315pub fn ok<T, E>(a: &Result<T, E>)
316where
317 T: Debug,
318 E: Debug,
319{
320 assert!(a.is_ok(), "Expected to be ok: {:?}", a);
321}
322
323#[track_caller]
338pub fn ok_into<T, E>(a: Result<T, E>) -> T
339where
340 T: Debug,
341 E: Debug,
342{
343 assert!(a.is_ok(), "Expected to be ok: {:?}", a);
344 a.unwrap()
345}
346
347#[track_caller]
361pub fn err<T, E>(a: &Result<T, E>)
362where
363 T: Debug,
364 E: Debug,
365{
366 assert!(a.is_err(), "Expected to be err: {:?}", a);
367}
368
369#[track_caller]
383pub fn err_into<T, E>(a: Result<T, E>) -> E
384where
385 T: Debug,
386 E: Debug,
387{
388 assert!(a.is_err(), "Expected to be err: {:?}", a);
389 a.unwrap_err()
390}
391
392#[track_caller]
406pub fn default<R>(a: &R)
407where
408 R: Default + Debug + PartialEq + ?Sized,
409{
410 assert_eq!(a, &R::default());
411}
412
413#[allow(clippy::ptr_arg)]
429#[track_caller]
430pub fn borrowed<R>(a: &Cow<'_, R>)
431where
432 R: Debug + PartialEq + ToOwned + ?Sized,
433{
434 assert!(
435 match a {
436 Cow::Borrowed(_) => true,
437 Cow::Owned(_) => false,
438 },
439 "Expected {:?} to be borrowed",
440 a.deref(),
441 );
442}
443
444#[allow(clippy::ptr_arg)]
460#[track_caller]
461pub fn owned<R>(a: &Cow<'_, R>)
462where
463 R: Debug + PartialEq + ToOwned + ?Sized,
464{
465 assert!(
466 match a {
467 Cow::Borrowed(_) => false,
468 Cow::Owned(_) => true,
469 },
470 "Expected {:?} to be owned",
471 a.deref(),
472 );
473}
474
475#[track_caller]
491pub fn cursor_completely_consumed<T>(cursor: &Cursor<T>)
492where
493 T: AsRef<[u8]>,
494{
495 assert_eq!(
496 cursor.position(),
497 cursor.get_ref().as_ref().len() as u64,
498 "Cursor was not completely consumed"
499 );
500}
501
502#[cfg(test)]
503mod tests {
504 use super::*;
505 use std::io::Result;
506
507 #[test]
508 fn test_ref_equal() {
509 let my_string = "abc";
510
511 ref_equal::<str>(&my_string, &"abc");
513 ref_equal::<str>(&my_string.to_string(), &"abc".to_string());
514
515 ref_equal(&my_string, &b"abc");
517 }
518
519 #[test]
520 fn test_equal() {
521 let result = "abc";
522 equal(result, "abc");
523 equal(&result, &"abc");
524 pretty_assertions::assert_eq!("abc".to_string(), "abc");
525 equal("abc".to_string(), "abc");
526 equal(5, 5);
527 equal(&5, &5);
528 equal(b"abc".as_slice(), b"abc".to_vec());
529 equal(Option::Some(Result::Ok(b"abc".to_vec())), b"abc".to_vec());
530 equal(Option::Some(Result::Ok(b"abc".as_slice())), b"abc".to_vec());
531 equal(Result::Ok(Option::Some(b"abc".to_vec())), b"abc".to_vec());
532 equal(Result::Ok(Option::Some(b"abc".as_slice())), b"abc".to_vec());
533 equal(Result::Ok(b"abc".to_vec()), b"abc".to_vec());
534 equal(Result::Ok(b"abc".to_vec()), b"abc".as_slice());
535 equal(Option::Some(b"abc".to_vec()), b"abc".to_vec());
536 equal(Option::Some(b"abc".to_vec()), b"abc".as_slice());
537 equal(Result::Ok(5), 5);
538 equal(Option::Some(5), 5);
539 equal(Result::Ok(Option::Some(5)), 5);
540 equal(Option::Some(Result::Ok(5)), 5);
541 }
542
543 #[test]
544 fn test_not_equal() {
545 let result = "abc";
546 not_equal(result, "def");
547 not_equal(result.as_bytes(), b"bcd");
548 pretty_assertions::assert_ne!("abc".to_string(), "def");
549 not_equal("abc".to_string(), "def");
550 not_equal(5, 4);
551 not_equal(&5, &4);
552 not_equal(Option::Some(Result::Ok(b"abc".to_vec())), b"def".to_vec());
553 not_equal(Option::Some(Result::Ok(b"abc".as_slice())), b"def".to_vec());
554 not_equal(Result::Ok(Option::Some(b"abc".to_vec())), b"def".to_vec());
555 not_equal(Result::Ok(Option::Some(b"abc".as_slice())), b"def".to_vec());
556 not_equal(Result::Ok(b"abc".to_vec()), b"def".to_vec());
557 not_equal(Result::Ok(b"abc".to_vec()), b"def".as_slice());
558 not_equal(Option::Some(b"abc".to_vec()), b"def".to_vec());
559 not_equal(Option::Some(b"abc".to_vec()), b"def".as_slice());
560 not_equal(Result::Ok(5), 4);
561 not_equal(Option::Some(5), 4);
562 not_equal(Result::Ok(Option::Some(5)), 4);
563 not_equal(Option::Some(Result::Ok(5)), 4);
564 }
565
566 #[test]
567 fn test_equal_bytes() {
568 let result = vec![0x01, 0x0E, 0xF3];
569 equal_bytes(&result, &[0x01, 0x0E, 0xF3]);
570 }
571
572 #[test]
573 fn test_equal_file_contents() {
574 let result1 = "some file content\n";
575 equal_file_contents(&result1, "./fixtures/test.txt");
576 }
577
578 #[test]
579 fn test_equal_hex_bytes() {
580 let result = vec![0x01, 0x0E, 0xF3];
581 equal_hex_bytes(&result, "010ef3");
582 }
583
584 #[test]
585 fn test_some() {
586 let result = Some("abc");
587 some(&result);
588 }
589
590 #[test]
591 fn test_some_into() {
592 let result = Some("abc");
593 let some = some_into(result);
594 equal(some, "abc");
595 }
596
597 #[test]
598 fn test_none() {
599 let result = None::<&str>;
600 none(&result);
601 }
602
603 #[test]
604 fn test_ok() {
605 let result = Result::Ok("abc");
606 ok(&result);
607 }
608
609 #[test]
610 fn test_ok_into() {
611 let result = Result::Ok("abc");
612 let ok = ok_into(result);
613 equal(ok, "abc");
614 }
615}