buup/transformers/
binary_decode.rs1use crate::{Transform, TransformError};
2
3#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
5pub struct BinaryDecode;
6
7impl Transform for BinaryDecode {
8 fn name(&self) -> &'static str {
9 "Binary Decode"
10 }
11
12 fn id(&self) -> &'static str {
13 "binarydecode"
14 }
15
16 fn description(&self) -> &'static str {
17 "Decode space-separated binary representation back to text."
18 }
19
20 fn category(&self) -> crate::TransformerCategory {
21 crate::TransformerCategory::Decoder
22 }
23
24 fn transform(&self, input: &str) -> Result<String, TransformError> {
25 if input.is_empty() {
26 return Ok(String::new());
27 }
28
29 let bytes: Result<Vec<u8>, _> = input
30 .split_whitespace()
31 .map(|s| {
32 if s.len() != 8 || !s.chars().all(|c| c == '0' || c == '1') {
33 Err(TransformError::InvalidArgument(
34 format!("Invalid 8-bit binary chunk: '{}'", s).into(),
35 ))
36 } else {
37 u8::from_str_radix(s, 2).map_err(|e| {
38 TransformError::InvalidArgument(
39 format!("Failed to parse binary chunk '{}': {}", s, e).into(),
40 )
41 })
42 }
43 })
44 .collect();
45
46 let bytes = bytes?;
47
48 String::from_utf8(bytes).map_err(|e| {
49 TransformError::InvalidArgument(format!("Invalid UTF-8 sequence: {}", e).into())
50 })
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn test_binary_decode_empty() {
60 let transformer = BinaryDecode;
61 let result = transformer.transform("").unwrap();
62 assert_eq!(result, "");
63 }
64
65 #[test]
66 fn test_binary_decode_simple() {
67 let transformer = BinaryDecode;
68 let result = transformer.transform("01001000 01101001").unwrap(); assert_eq!(result, "Hi");
70 }
71
72 #[test]
73 fn test_binary_decode_with_punctuation() {
74 let transformer = BinaryDecode;
75 let input = "01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001"; let result = transformer.transform(input).unwrap();
77 assert_eq!(result, "Hello, World!");
78 }
79
80 #[test]
81 fn test_binary_decode_unicode() {
82 let transformer = BinaryDecode;
83 let input = "11100010 10011100 10010011"; let result = transformer.transform(input).unwrap();
85 assert_eq!(result, "✓");
86 }
87
88 #[test]
89 fn test_binary_decode_invalid_length() {
90 let transformer = BinaryDecode;
91 let result = transformer.transform("01001000 1101001"); assert!(result.is_err());
93 match result {
94 Err(TransformError::InvalidArgument(msg)) => {
95 assert!(msg.contains("Invalid 8-bit binary chunk: '1101001'"));
96 }
97 _ => panic!("Expected InvalidArgument error"),
98 }
99 }
100
101 #[test]
102 fn test_binary_decode_invalid_chars() {
103 let transformer = BinaryDecode;
104 let result = transformer.transform("01001000 0110100a"); assert!(result.is_err());
106 match result {
107 Err(TransformError::InvalidArgument(msg)) => {
108 assert!(msg.contains("Invalid 8-bit binary chunk: '0110100a'"));
109 }
110 _ => panic!("Expected InvalidArgument error"),
111 }
112 }
113
114 #[test]
115 fn test_binary_decode_invalid_utf8() {
116 let transformer = BinaryDecode;
117 let result = transformer.transform("11110000 10011111 10011111"); assert!(result.is_err());
119 match result {
120 Err(TransformError::InvalidArgument(msg)) => {
121 assert!(msg.contains("Invalid UTF-8 sequence"));
122 }
123 _ => panic!("Expected InvalidArgument error"),
124 }
125 }
126
127 #[test]
128 fn test_binary_decode_trailing_space() {
129 let transformer = BinaryDecode;
130 let result = transformer.transform("01001000 ").unwrap(); assert_eq!(result, "H");
132 }
133
134 #[test]
135 fn test_binary_decode_leading_space() {
136 let transformer = BinaryDecode;
137 let result = transformer.transform(" 01001000").unwrap(); assert_eq!(result, "H");
139 }
140}