yaml_edit/scalar/
binary.rs1use base64::{engine::general_purpose, Engine as _};
4
5use super::{ScalarStyle, ScalarType, ScalarValue};
6
7fn base64_encode(input: &[u8]) -> String {
9 general_purpose::STANDARD.encode(input)
10}
11
12pub(super) fn base64_decode(input: &str) -> Result<Vec<u8>, String> {
14 general_purpose::STANDARD
15 .decode(input.trim())
16 .map_err(|e| format!("Base64 decode error: {e}"))
17}
18
19impl ScalarValue {
20 pub fn binary(data: &[u8]) -> Self {
22 let encoded = base64_encode(data);
23 Self {
24 value: encoded,
25 style: ScalarStyle::Plain,
26 scalar_type: ScalarType::Binary,
27 tag: None,
28 }
29 }
30
31 pub fn as_binary(&self) -> Option<Result<Vec<u8>, String>> {
33 match self.scalar_type {
34 ScalarType::Binary => Some(base64_decode(&self.value)),
35 _ => None,
36 }
37 }
38
39 pub fn is_binary(&self) -> bool {
41 self.scalar_type == ScalarType::Binary
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn test_binary_data_encoding() {
51 let data = b"Hello, World!";
53 let scalar = ScalarValue::binary(data);
54
55 assert!(scalar.is_binary());
56 assert_eq!(scalar.scalar_type(), ScalarType::Binary);
57
58 let yaml_output = scalar.to_yaml_string();
60 assert!(yaml_output.starts_with("!!binary "));
61
62 if let Some(decoded_result) = scalar.as_binary() {
64 let decoded = decoded_result.expect("Should decode successfully");
65 assert_eq!(decoded, data);
66 } else {
67 panic!("Should be able to extract binary data");
68 }
69 }
70
71 #[test]
72 fn test_base64_encoding_decoding() {
73 let test_cases = [
75 b"".as_slice(),
76 b"A",
77 b"AB",
78 b"ABC",
79 b"ABCD",
80 b"Hello, World!",
81 &[0, 1, 2, 3, 255, 254, 253],
82 ];
83
84 for data in test_cases {
85 let encoded = base64_encode(data);
86 let decoded = base64_decode(&encoded).expect("Should decode successfully");
87 assert_eq!(decoded, data, "Failed for data: {:?}", data);
88 }
89 }
90}