1use crate::value_map::ValueMapHelper;
2use crate::{Error, Value};
3use std::collections::BTreeMap;
4
5use base64::prelude::BASE64_STANDARD;
6use base64::Engine;
7use std::iter::Peekable;
8use std::vec::IntoIter;
9
10#[derive(Debug, Clone, Copy)]
11pub enum IntegerReplacementType {
12 U128,
13 I128,
14 U64,
15 I64,
16 U32,
17 I32,
18 U16,
19 I16,
20 U8,
21 I8,
22}
23
24impl IntegerReplacementType {
25 pub fn replace_for_value(&self, value: Value) -> Result<Value, Error> {
26 Ok(match self {
27 IntegerReplacementType::U128 => Value::U128(value.try_into()?),
28 IntegerReplacementType::I128 => Value::I128(value.try_into()?),
29 IntegerReplacementType::U64 => Value::U64(value.try_into()?),
30 IntegerReplacementType::I64 => Value::I64(value.try_into()?),
31 IntegerReplacementType::U32 => Value::U32(value.try_into()?),
32 IntegerReplacementType::I32 => Value::I32(value.try_into()?),
33 IntegerReplacementType::U16 => Value::U16(value.try_into()?),
34 IntegerReplacementType::I16 => Value::I16(value.try_into()?),
35 IntegerReplacementType::U8 => Value::U8(value.try_into()?),
36 IntegerReplacementType::I8 => Value::I8(value.try_into()?),
37 })
38 }
39}
40
41#[derive(Debug, Clone, Copy)]
42pub enum ReplacementType {
43 Identifier,
44 BinaryBytes,
45 TextBase58,
46 TextBase64,
47}
48
49impl ReplacementType {
50 pub fn replace_for_bytes(&self, bytes: Vec<u8>) -> Result<Value, Error> {
51 match self {
52 ReplacementType::Identifier => {
53 Ok(Value::Identifier(bytes.try_into().map_err(|_| {
54 Error::ByteLengthNot32BytesError(String::from(
55 "Trying to replace into an identifier, but not 32 bytes long",
56 ))
57 })?))
58 }
59 ReplacementType::BinaryBytes => Ok(Value::Bytes(bytes)),
60 ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())),
61 ReplacementType::TextBase64 => Ok(Value::Text(BASE64_STANDARD.encode(bytes))),
62 }
63 }
64
65 pub fn replace_for_bytes_20(&self, bytes: [u8; 20]) -> Result<Value, Error> {
66 match self {
67 ReplacementType::BinaryBytes => Ok(Value::Bytes20(bytes)),
68 ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())),
69 ReplacementType::TextBase64 => Ok(Value::Text(BASE64_STANDARD.encode(bytes))),
70 _ => Err(Error::ByteLengthNot36BytesError(
71 "trying to replace 36 bytes into an identifier".to_string(),
72 )),
73 }
74 }
75
76 pub fn replace_for_bytes_32(&self, bytes: [u8; 32]) -> Result<Value, Error> {
77 match self {
78 ReplacementType::Identifier => Ok(Value::Identifier(bytes)),
79 ReplacementType::BinaryBytes => Ok(Value::Bytes32(bytes)),
80 ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())),
81 ReplacementType::TextBase64 => Ok(Value::Text(BASE64_STANDARD.encode(bytes))),
82 }
83 }
84
85 pub fn replace_for_bytes_36(&self, bytes: [u8; 36]) -> Result<Value, Error> {
86 match self {
87 ReplacementType::BinaryBytes => Ok(Value::Bytes36(bytes)),
88 ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())),
89 ReplacementType::TextBase64 => Ok(Value::Text(BASE64_STANDARD.encode(bytes))),
90 _ => Err(Error::ByteLengthNot36BytesError(
91 "trying to replace 36 bytes into an identifier".to_string(),
92 )),
93 }
94 }
95
96 pub fn replace_consume_value(&self, value: Value) -> Result<Value, Error> {
97 let bytes = value.into_identifier_bytes()?;
98 self.replace_for_bytes(bytes)
99 }
100
101 pub fn replace_value_in_place(&self, value: &mut Value) -> Result<(), Error> {
102 let bytes = value.take().into_identifier_bytes()?;
103 *value = self.replace_for_bytes(bytes)?;
104 Ok(())
105 }
106}
107
108pub trait BTreeValueMapReplacementPathHelper {
109 fn replace_at_path(
110 &mut self,
111 path: &str,
112 replacement_type: ReplacementType,
113 ) -> Result<(), Error>;
114 fn replace_at_paths<'a, I: IntoIterator<Item = &'a String>>(
115 &mut self,
116 paths: I,
117 replacement_type: ReplacementType,
118 ) -> Result<(), Error>;
119}
120
121fn replace_down(
122 mut current_values: Vec<&mut Value>,
123 mut split: Peekable<IntoIter<&str>>,
124 replacement_type: ReplacementType,
125) -> Result<(), Error> {
126 if let Some(path_component) = split.next() {
127 let next_values = current_values
128 .iter_mut()
129 .map(|current_value| {
130 if current_value.is_map() {
131 let map = current_value.as_map_mut_ref()?;
132 let Some(new_value) = map.get_optional_key_mut(path_component) else {
133 return Ok(None);
134 };
135 if split.peek().is_none() {
136 match new_value {
137 Value::Bytes20(bytes) => {
138 *new_value = replacement_type.replace_for_bytes_20(*bytes)?;
139 }
140 Value::Bytes32(bytes) => {
141 *new_value = replacement_type.replace_for_bytes_32(*bytes)?;
142 }
143 Value::Bytes36(bytes) => {
144 *new_value = replacement_type.replace_for_bytes_36(*bytes)?;
145 }
146 _ => {
147 let bytes = match replacement_type {
148 ReplacementType::Identifier | ReplacementType::TextBase58 => {
149 new_value.to_identifier_bytes()
150 }
151 ReplacementType::BinaryBytes | ReplacementType::TextBase64 => {
152 new_value.to_binary_bytes()
153 }
154 }?;
155 *new_value = replacement_type.replace_for_bytes(bytes)?;
156 }
157 }
158 Ok(None)
159 } else {
160 Ok(Some(vec![new_value]))
161 }
162 } else if current_value.is_array() {
163 let array = current_value.to_array_mut()?.iter_mut().collect();
165 Ok(Some(array))
166 } else {
167 Err(Error::PathError("path was not an array or map".to_string()))
168 }
169 })
170 .collect::<Result<Vec<_>, Error>>()?
171 .into_iter()
172 .flatten()
173 .flatten()
174 .collect();
175 replace_down(next_values, split, replacement_type)
176 } else {
177 Ok(())
178 }
179}
180
181impl BTreeValueMapReplacementPathHelper for BTreeMap<String, Value> {
182 fn replace_at_path(
183 &mut self,
184 path: &str,
185 replacement_type: ReplacementType,
186 ) -> Result<(), Error> {
187 let mut split: Vec<_> = path.split('.').collect();
188 let first = split.first();
189 let Some(first_path_component) = first else {
190 return Err(Error::PathError("path was empty".to_string()));
191 };
192 let Some(current_value) = self.get_mut(first_path_component.to_owned()) else {
193 return Ok(());
194 };
195 if split.len() == 1 {
196 match current_value {
197 Value::Bytes20(bytes) => {
198 *current_value = replacement_type.replace_for_bytes_20(*bytes)?;
199 }
200 Value::Bytes32(bytes) => {
201 *current_value = replacement_type.replace_for_bytes_32(*bytes)?;
202 }
203 Value::Bytes36(bytes) => {
204 *current_value = replacement_type.replace_for_bytes_36(*bytes)?;
205 }
206 _ => {
207 let bytes = match replacement_type {
208 ReplacementType::Identifier | ReplacementType::TextBase58 => {
209 current_value.to_identifier_bytes()
210 }
211 ReplacementType::BinaryBytes | ReplacementType::TextBase64 => {
212 current_value.to_binary_bytes()
213 }
214 }?;
215 *current_value = replacement_type.replace_for_bytes(bytes)?;
216 }
217 }
218 Ok(())
219 } else {
220 split.remove(0);
221 let current_values = vec![current_value];
222 replace_down(
224 current_values,
225 split.into_iter().peekable(),
226 replacement_type,
227 )
228 }
229 }
230
231 fn replace_at_paths<'a, I: IntoIterator<Item = &'a String>>(
232 &mut self,
233 paths: I,
234 replacement_type: ReplacementType,
235 ) -> Result<(), Error> {
236 paths
237 .into_iter()
238 .try_for_each(|path| self.replace_at_path(path.as_str(), replacement_type))
239 }
240}
241
242#[cfg(test)]
243mod tests {
244 use super::*;
245 use crate::value_map::ValueMapHelper;
246 use crate::{Error, Value};
247 use base64::prelude::BASE64_STANDARD;
248 use base64::Engine;
249 use std::collections::BTreeMap;
250
251 #[test]
256 fn integer_replacement_u8() {
257 let result = IntegerReplacementType::U8
258 .replace_for_value(Value::U64(200))
259 .unwrap();
260 assert_eq!(result, Value::U8(200));
261 }
262
263 #[test]
264 fn integer_replacement_i8() {
265 let result = IntegerReplacementType::I8
266 .replace_for_value(Value::I64(-100))
267 .unwrap();
268 assert_eq!(result, Value::I8(-100));
269 }
270
271 #[test]
272 fn integer_replacement_u16() {
273 let result = IntegerReplacementType::U16
274 .replace_for_value(Value::U64(60000))
275 .unwrap();
276 assert_eq!(result, Value::U16(60000));
277 }
278
279 #[test]
280 fn integer_replacement_i16() {
281 let result = IntegerReplacementType::I16
282 .replace_for_value(Value::I64(-30000))
283 .unwrap();
284 assert_eq!(result, Value::I16(-30000));
285 }
286
287 #[test]
288 fn integer_replacement_u32() {
289 let result = IntegerReplacementType::U32
290 .replace_for_value(Value::U64(3_000_000))
291 .unwrap();
292 assert_eq!(result, Value::U32(3_000_000));
293 }
294
295 #[test]
296 fn integer_replacement_i32() {
297 let result = IntegerReplacementType::I32
298 .replace_for_value(Value::I64(-3_000_000))
299 .unwrap();
300 assert_eq!(result, Value::I32(-3_000_000));
301 }
302
303 #[test]
304 fn integer_replacement_u64() {
305 let result = IntegerReplacementType::U64
306 .replace_for_value(Value::U64(u64::MAX))
307 .unwrap();
308 assert_eq!(result, Value::U64(u64::MAX));
309 }
310
311 #[test]
312 fn integer_replacement_i64() {
313 let result = IntegerReplacementType::I64
314 .replace_for_value(Value::I64(i64::MIN))
315 .unwrap();
316 assert_eq!(result, Value::I64(i64::MIN));
317 }
318
319 #[test]
320 fn integer_replacement_u128() {
321 let result = IntegerReplacementType::U128
322 .replace_for_value(Value::U64(42))
323 .unwrap();
324 assert_eq!(result, Value::U128(42));
325 }
326
327 #[test]
328 fn integer_replacement_i128() {
329 let result = IntegerReplacementType::I128
330 .replace_for_value(Value::I64(-42))
331 .unwrap();
332 assert_eq!(result, Value::I128(-42));
333 }
334
335 #[test]
336 fn integer_replacement_overflow_error() {
337 let result = IntegerReplacementType::U8.replace_for_value(Value::U64(300));
339 assert!(result.is_err());
340 }
341
342 #[test]
343 fn integer_replacement_non_integer_error() {
344 let result =
346 IntegerReplacementType::U64.replace_for_value(Value::Text("not a number".into()));
347 assert!(result.is_err());
348 }
349
350 #[test]
355 fn replace_for_bytes_identifier_32_bytes_ok() {
356 let bytes = vec![0xABu8; 32];
357 let result = ReplacementType::Identifier
358 .replace_for_bytes(bytes.clone())
359 .unwrap();
360 let expected: [u8; 32] = bytes.try_into().unwrap();
361 assert_eq!(result, Value::Identifier(expected));
362 }
363
364 #[test]
365 fn replace_for_bytes_identifier_wrong_size() {
366 let bytes = vec![0xABu8; 31]; let result = ReplacementType::Identifier.replace_for_bytes(bytes);
368 assert!(matches!(result, Err(Error::ByteLengthNot32BytesError(_))));
369 }
370
371 #[test]
372 fn replace_for_bytes_identifier_too_long() {
373 let bytes = vec![0xABu8; 33];
374 let result = ReplacementType::Identifier.replace_for_bytes(bytes);
375 assert!(matches!(result, Err(Error::ByteLengthNot32BytesError(_))));
376 }
377
378 #[test]
379 fn replace_for_bytes_binary_bytes() {
380 let bytes = vec![1, 2, 3, 4, 5];
381 let result = ReplacementType::BinaryBytes
382 .replace_for_bytes(bytes.clone())
383 .unwrap();
384 assert_eq!(result, Value::Bytes(bytes));
385 }
386
387 #[test]
388 fn replace_for_bytes_text_base58() {
389 let bytes = vec![0x01, 0x02, 0x03];
390 let expected = bs58::encode(&bytes).into_string();
391 let result = ReplacementType::TextBase58
392 .replace_for_bytes(bytes)
393 .unwrap();
394 assert_eq!(result, Value::Text(expected));
395 }
396
397 #[test]
398 fn replace_for_bytes_text_base64() {
399 let bytes = vec![0xDE, 0xAD, 0xBE, 0xEF];
400 let expected = BASE64_STANDARD.encode(&bytes);
401 let result = ReplacementType::TextBase64
402 .replace_for_bytes(bytes)
403 .unwrap();
404 assert_eq!(result, Value::Text(expected));
405 }
406
407 #[test]
412 fn replace_for_bytes_20_binary() {
413 let bytes = [0xFFu8; 20];
414 let result = ReplacementType::BinaryBytes
415 .replace_for_bytes_20(bytes)
416 .unwrap();
417 assert_eq!(result, Value::Bytes20(bytes));
418 }
419
420 #[test]
421 fn replace_for_bytes_20_text_base58() {
422 let bytes = [0x01u8; 20];
423 let expected = bs58::encode(bytes).into_string();
424 let result = ReplacementType::TextBase58
425 .replace_for_bytes_20(bytes)
426 .unwrap();
427 assert_eq!(result, Value::Text(expected));
428 }
429
430 #[test]
431 fn replace_for_bytes_20_text_base64() {
432 let bytes = [0x02u8; 20];
433 let expected = BASE64_STANDARD.encode(bytes);
434 let result = ReplacementType::TextBase64
435 .replace_for_bytes_20(bytes)
436 .unwrap();
437 assert_eq!(result, Value::Text(expected));
438 }
439
440 #[test]
441 fn replace_for_bytes_20_identifier_error() {
442 let bytes = [0xAAu8; 20];
443 let result = ReplacementType::Identifier.replace_for_bytes_20(bytes);
444 assert!(matches!(result, Err(Error::ByteLengthNot36BytesError(_))));
445 }
446
447 #[test]
452 fn replace_for_bytes_32_identifier() {
453 let bytes = [0xBBu8; 32];
454 let result = ReplacementType::Identifier
455 .replace_for_bytes_32(bytes)
456 .unwrap();
457 assert_eq!(result, Value::Identifier(bytes));
458 }
459
460 #[test]
461 fn replace_for_bytes_32_binary() {
462 let bytes = [0xCCu8; 32];
463 let result = ReplacementType::BinaryBytes
464 .replace_for_bytes_32(bytes)
465 .unwrap();
466 assert_eq!(result, Value::Bytes32(bytes));
467 }
468
469 #[test]
470 fn replace_for_bytes_32_text_base58() {
471 let bytes = [0x01u8; 32];
472 let expected = bs58::encode(bytes).into_string();
473 let result = ReplacementType::TextBase58
474 .replace_for_bytes_32(bytes)
475 .unwrap();
476 assert_eq!(result, Value::Text(expected));
477 }
478
479 #[test]
480 fn replace_for_bytes_32_text_base64() {
481 let bytes = [0x02u8; 32];
482 let expected = BASE64_STANDARD.encode(bytes);
483 let result = ReplacementType::TextBase64
484 .replace_for_bytes_32(bytes)
485 .unwrap();
486 assert_eq!(result, Value::Text(expected));
487 }
488
489 #[test]
494 fn replace_for_bytes_36_binary() {
495 let bytes = [0xDDu8; 36];
496 let result = ReplacementType::BinaryBytes
497 .replace_for_bytes_36(bytes)
498 .unwrap();
499 assert_eq!(result, Value::Bytes36(bytes));
500 }
501
502 #[test]
503 fn replace_for_bytes_36_text_base58() {
504 let bytes = [0x03u8; 36];
505 let expected = bs58::encode(bytes).into_string();
506 let result = ReplacementType::TextBase58
507 .replace_for_bytes_36(bytes)
508 .unwrap();
509 assert_eq!(result, Value::Text(expected));
510 }
511
512 #[test]
513 fn replace_for_bytes_36_text_base64() {
514 let bytes = [0x04u8; 36];
515 let expected = BASE64_STANDARD.encode(bytes);
516 let result = ReplacementType::TextBase64
517 .replace_for_bytes_36(bytes)
518 .unwrap();
519 assert_eq!(result, Value::Text(expected));
520 }
521
522 #[test]
523 fn replace_for_bytes_36_identifier_error() {
524 let bytes = [0xEEu8; 36];
525 let result = ReplacementType::Identifier.replace_for_bytes_36(bytes);
526 assert!(matches!(result, Err(Error::ByteLengthNot36BytesError(_))));
527 }
528
529 #[test]
534 fn replace_at_path_single_segment_bytes32() {
535 let bytes = [0xABu8; 32];
536 let mut map = BTreeMap::new();
537 map.insert("id".to_string(), Value::Bytes32(bytes));
538
539 map.replace_at_path("id", ReplacementType::Identifier)
540 .unwrap();
541 assert_eq!(map.get("id"), Some(&Value::Identifier(bytes)));
542 }
543
544 #[test]
545 fn replace_at_path_single_segment_bytes20() {
546 let bytes = [0x11u8; 20];
547 let mut map = BTreeMap::new();
548 map.insert("addr".to_string(), Value::Bytes20(bytes));
549
550 map.replace_at_path("addr", ReplacementType::BinaryBytes)
551 .unwrap();
552 assert_eq!(map.get("addr"), Some(&Value::Bytes20(bytes)));
553 }
554
555 #[test]
556 fn replace_at_path_single_segment_bytes36() {
557 let bytes = [0x22u8; 36];
558 let mut map = BTreeMap::new();
559 map.insert("outpoint".to_string(), Value::Bytes36(bytes));
560
561 map.replace_at_path("outpoint", ReplacementType::BinaryBytes)
562 .unwrap();
563 assert_eq!(map.get("outpoint"), Some(&Value::Bytes36(bytes)));
564 }
565
566 #[test]
567 fn replace_at_path_single_segment_identifier_to_base58() {
568 let bytes = [0xCCu8; 32];
569 let mut map = BTreeMap::new();
570 map.insert("id".to_string(), Value::Identifier(bytes));
571
572 map.replace_at_path("id", ReplacementType::TextBase58)
573 .unwrap();
574 let expected = bs58::encode(bytes).into_string();
575 assert_eq!(map.get("id"), Some(&Value::Text(expected)));
576 }
577
578 #[test]
583 fn replace_at_path_nested() {
584 let bytes = [0xFFu8; 32];
585 let inner_map = vec![(Value::Text("nested_id".into()), Value::Bytes32(bytes))];
586 let mut map = BTreeMap::new();
587 map.insert("parent".to_string(), Value::Map(inner_map));
588
589 map.replace_at_path("parent.nested_id", ReplacementType::Identifier)
590 .unwrap();
591
592 let parent = map.get("parent").unwrap();
593 if let Value::Map(inner) = parent {
594 let val = inner.get_optional_key("nested_id").unwrap();
595 assert_eq!(*val, Value::Identifier(bytes));
596 } else {
597 panic!("expected Map");
598 }
599 }
600
601 #[test]
602 fn replace_at_path_deep_nested() {
603 let bytes = [0xAAu8; 32];
604 let level2 = vec![(Value::Text("deep_id".into()), Value::Bytes32(bytes))];
605 let level1 = vec![(Value::Text("level2".into()), Value::Map(level2))];
606 let mut map = BTreeMap::new();
607 map.insert("level1".to_string(), Value::Map(level1));
608
609 map.replace_at_path("level1.level2.deep_id", ReplacementType::Identifier)
610 .unwrap();
611
612 let l1 = map.get("level1").unwrap();
613 if let Value::Map(l1_map) = l1 {
614 let l2 = l1_map.get_optional_key("level2").unwrap();
615 if let Value::Map(l2_map) = l2 {
616 let val = l2_map.get_optional_key("deep_id").unwrap();
617 assert_eq!(*val, Value::Identifier(bytes));
618 } else {
619 panic!("expected Map at level2");
620 }
621 } else {
622 panic!("expected Map at level1");
623 }
624 }
625
626 #[test]
631 fn replace_at_path_through_array_applies_to_elements() {
632 let bytes1 = [0x11u8; 32];
647 let bytes2 = [0x22u8; 32];
648 let item1 = Value::Map(vec![(Value::Text("id".into()), Value::Bytes32(bytes1))]);
649 let item2 = Value::Map(vec![(Value::Text("id".into()), Value::Bytes32(bytes2))]);
650 let wrapper_map = vec![(Value::Text("arr".into()), Value::Array(vec![item1, item2]))];
651 let mut map = BTreeMap::new();
652 map.insert("wrapper".to_string(), Value::Map(wrapper_map));
653
654 map.replace_at_path("wrapper.arr.placeholder.id", ReplacementType::Identifier)
656 .unwrap();
657
658 if let Value::Map(wrapper) = map.get("wrapper").unwrap() {
659 let arr_val = wrapper.get_optional_key("arr").unwrap();
660 if let Value::Array(arr) = arr_val {
661 assert_eq!(arr.len(), 2);
662 for (i, item) in arr.iter().enumerate() {
663 if let Value::Map(m) = item {
664 let val = m.get_optional_key("id").unwrap();
665 let expected_bytes = if i == 0 { bytes1 } else { bytes2 };
666 assert_eq!(*val, Value::Identifier(expected_bytes));
667 } else {
668 panic!("expected Map in array");
669 }
670 }
671 } else {
672 panic!("expected Array");
673 }
674 } else {
675 panic!("expected Map at wrapper");
676 }
677 }
678
679 #[test]
684 fn replace_at_path_empty_path_error() {
685 let mut map = BTreeMap::new();
686 map.insert("key".to_string(), Value::U64(1));
687 let result = map.replace_at_path("", ReplacementType::Identifier);
688 assert!(result.is_ok());
692 }
693
694 #[test]
695 fn replace_at_path_missing_key_returns_ok() {
696 let mut map = BTreeMap::new();
697 map.insert("key".to_string(), Value::U64(1));
698 let result = map.replace_at_path("nonexistent", ReplacementType::BinaryBytes);
700 assert!(result.is_ok());
701 }
702
703 #[test]
704 fn replace_at_path_non_map_value_in_nested_path_error() {
705 let mut map = BTreeMap::new();
706 map.insert("key".to_string(), Value::U64(42));
707 let result = map.replace_at_path("key.sub", ReplacementType::BinaryBytes);
709 assert!(matches!(result, Err(Error::PathError(_))));
710 }
711
712 #[test]
717 fn replace_at_paths_multiple() {
718 let bytes1 = [0xAAu8; 32];
719 let bytes2 = [0xBBu8; 32];
720 let mut map = BTreeMap::new();
721 map.insert("id1".to_string(), Value::Bytes32(bytes1));
722 map.insert("id2".to_string(), Value::Bytes32(bytes2));
723
724 let paths = vec!["id1".to_string(), "id2".to_string()];
725 map.replace_at_paths(&paths, ReplacementType::Identifier)
726 .unwrap();
727
728 assert_eq!(map.get("id1"), Some(&Value::Identifier(bytes1)));
729 assert_eq!(map.get("id2"), Some(&Value::Identifier(bytes2)));
730 }
731
732 #[test]
737 fn replace_consume_value_identifier_to_base58() {
738 let bytes = [0xCCu8; 32];
739 let val = Value::Identifier(bytes);
740 let result = ReplacementType::TextBase58
741 .replace_consume_value(val)
742 .unwrap();
743 let expected = bs58::encode(bytes).into_string();
744 assert_eq!(result, Value::Text(expected));
745 }
746
747 #[test]
748 fn replace_value_in_place_identifier_to_binary() {
749 let bytes = [0xDDu8; 32];
750 let mut val = Value::Identifier(bytes);
751 ReplacementType::BinaryBytes
752 .replace_value_in_place(&mut val)
753 .unwrap();
754 assert_eq!(val, Value::Bytes(bytes.to_vec()));
755 }
756}