| 114 | #[track_caller] |
| 115 | #[expect(clippy::needless_pass_by_value)] |
| 116 | pub(crate) fn assert_encode<T>(value: &T, expected: Expect) |
| 117 | where |
| 118 | T: Encode + Sync, |
| 119 | { |
| 120 | let buffer = encode_value(value); |
| 121 | |
| 122 | // every line has 16 bytes, each byte at most is represented by 5 characters. With an |
| 123 | // additional newline. |
| 124 | let lines = buffer.len().div_ceil(16); |
| 125 | let capacity = (lines * (16 * 5)) + lines; |
| 126 | |
| 127 | let mut output = String::with_capacity(capacity); |
| 128 | |
| 129 | // first section into lines (of size 16) |
| 130 | let chunks = buffer.chunks(16); |
| 131 | |
| 132 | for chunk in chunks { |
| 133 | for (index, &byte) in chunk.iter().enumerate() { |
| 134 | if index > 0 { |
| 135 | output.push(' '); |
| 136 | } |
| 137 | |
| 138 | if byte.is_ascii_graphic() || byte.is_ascii_whitespace() { |
| 139 | // at most is 4 characters, align to the right |
| 140 | let escaped = byte.escape_ascii(); |
| 141 | // we never generate \xNN and never an empty string |
| 142 | assert!(escaped.len() <= 2 && escaped.len() > 0); |
| 143 | |
| 144 | let padding = 2 - escaped.len(); |
| 145 | |
| 146 | match padding { |
| 147 | 0 => {} |
| 148 | 1 => output.push('b'), |
| 149 | _ => unreachable!(), |
| 150 | } |
| 151 | |
| 152 | output.push('\''); |
| 153 | for char in escaped { |
| 154 | output.push(char as char); |
| 155 | } |
| 156 | output.push('\''); |
| 157 | } else { |
| 158 | write!(output, "{byte:#04X}").expect("infallible"); |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | output.push('\n'); |
| 163 | } |
| 164 | |
| 165 | expected.assert_eq(&output); |
| 166 | } |
| 167 | |
| 168 | #[track_caller] |
| 169 | pub(crate) fn assert_encode_error<T>(value: &T, expected: &T::Error) |