tag2upload_service_manager/
fmt_cmp.rs1use crate::prelude::*;
4
5struct State<'s> {
6 remain: Result<&'s str, Differs>,
7}
8
9#[derive(Copy, Clone)]
10struct Differs;
11
12impl From<Differs> for fmt::Error {
13 fn from(Differs: Differs) -> fmt::Error { fmt::Error }
14}
15
16impl fmt::Write for State<'_> {
17 fn write_str(&mut self, chunk: &str) -> fmt::Result {
18 self.remain = self.remain?.strip_prefix(chunk).ok_or(Differs);
19 self.remain?;
20 Ok(())
21 }
22}
23
24pub fn display_eq(s: &str, t: impl Display) -> bool {
25 let mut state = State { remain: Ok(s) };
26 match (write!(&mut state, "{}", t), state.remain) {
27 (Ok(()), Ok(remain)) => remain.is_empty(),
28 (_, Err(Differs)) => false,
29 (Err(fmt::Error), Ok(_)) => panic!("display impl panicked"),
30 }
31}
32
33#[test]
34fn test() {
35 struct DisplayStrs<'s>(&'s [&'s str]);
36 impl Display for DisplayStrs<'_> {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 for s in self.0 {
39 Display::fmt(s, f)?;
40 }
41 Ok(())
42 }
43 }
44
45 let chk = |eq, s, l| {
46 assert_eq!(
47 eq,
48 display_eq(s, DisplayStrs(l)),
49 "{s:?} {l:?}",
50 );
51 };
52
53 chk(true, "abc", &["abc"]);
54 chk(true, "abc", &["a", "bc"]);
55 chk(true, "abc", &["a", "", "bc"]);
56 chk(true, "abc", &["a", "", "bc", ""]);
57
58 chk(false, "abc", &["ab"]);
59 chk(false, "abc", &["a", "b"]);
60 chk(false, "abc", &["", "a", "", "b", ""]);
61
62 chk(false, "abc", &["abcd"]);
63 chk(false, "abc", &["ab", "cd"]);
64 chk(false, "abc", &["ab", "c", "d"]);
65 chk(false, "abc", &["ab", "c", "", "d"]);
66
67 chk(false, "abc", &["ab2"]);
68 chk(false, "abc", &["ab", "2"]);
69}