cfx_rpc_primitives/
bytes.rs1use core::{
24 borrow::Borrow,
25 ops::{Deref, DerefMut},
26};
27use rustc_hex::{FromHex, ToHex};
28use serde::{
29 de::{Error, Visitor},
30 Deserialize, Deserializer, Serialize, Serializer,
31};
32use std::fmt;
33
34#[derive(Debug, PartialEq, Eq, Default, Hash, Clone)]
36#[allow(dead_code)]
37pub struct Bytes(pub Vec<u8>);
38
39impl Bytes {
40 pub fn new(bytes: Vec<u8>) -> Bytes { Bytes(bytes) }
42
43 #[allow(dead_code)]
45 pub fn into_vec(self) -> Vec<u8> { self.0 }
46}
47
48impl From<Vec<u8>> for Bytes {
49 fn from(bytes: Vec<u8>) -> Bytes { Bytes(bytes) }
50}
51
52impl Into<Vec<u8>> for Bytes {
53 fn into(self) -> Vec<u8> { self.0 }
54}
55
56impl Deref for Bytes {
57 type Target = Vec<u8>;
58
59 #[inline]
60 fn deref(&self) -> &Self::Target { &self.0 }
61}
62
63impl DerefMut for Bytes {
64 #[inline]
65 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
66}
67
68impl AsRef<[u8]> for Bytes {
69 #[inline]
70 fn as_ref(&self) -> &[u8] { self.0.as_ref() }
71}
72
73impl Borrow<[u8]> for Bytes {
74 #[inline]
75 fn borrow(&self) -> &[u8] { self.as_ref() }
76}
77
78impl Serialize for Bytes {
79 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
80 where S: Serializer {
81 let mut serialized = "0x".to_owned();
82 serialized.push_str(self.0.to_hex::<String>().as_ref());
83 serializer.serialize_str(serialized.as_ref())
84 }
85}
86
87impl<'a> Deserialize<'a> for Bytes {
88 fn deserialize<D>(deserializer: D) -> Result<Bytes, D::Error>
89 where D: Deserializer<'a> {
90 deserializer.deserialize_any(BytesVisitor)
91 }
92}
93
94struct BytesVisitor;
95
96impl<'a> Visitor<'a> for BytesVisitor {
97 type Value = Bytes;
98
99 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
100 write!(formatter, "a 0x-prefixed, hex-encoded vector of bytes")
101 }
102
103 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
104 where E: Error {
105 if let (Some(s), true) =
106 (value.strip_prefix("0x"), value.len() & 1 == 0)
107 {
108 Ok(Bytes::new(FromHex::from_hex(s).map_err(|e| {
109 Error::custom(format!("Invalid hex: {}", e))
110 })?))
111 } else {
112 Err(Error::custom("Invalid bytes format. Expected a 0x-prefixed hex string with even length"))
113 }
114 }
115
116 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
117 where E: Error {
118 self.visit_str(value.as_ref())
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use rustc_hex::FromHex;
125 use serde_json;
126
127 use super::*;
128
129 #[test]
130 fn test_bytes_serialize() {
131 let bytes = Bytes("0123456789abcdef".from_hex().unwrap());
132 let serialized = serde_json::to_string(&bytes).unwrap();
133 assert_eq!(serialized, r#""0x0123456789abcdef""#);
134 }
135
136 #[test]
137 fn test_bytes_deserialize() {
138 let bytes1: Result<Bytes, serde_json::Error> =
139 serde_json::from_str(r#""""#);
140 let bytes2: Result<Bytes, serde_json::Error> =
141 serde_json::from_str(r#""0x123""#);
142 let bytes3: Result<Bytes, serde_json::Error> =
143 serde_json::from_str(r#""0xgg""#);
144
145 let bytes4: Bytes = serde_json::from_str(r#""0x""#).unwrap();
146 let bytes5: Bytes = serde_json::from_str(r#""0x12""#).unwrap();
147 let bytes6: Bytes = serde_json::from_str(r#""0x0123""#).unwrap();
148
149 assert!(bytes1.is_err());
150 assert!(bytes2.is_err());
151 assert!(bytes3.is_err());
152 assert_eq!(bytes4, Bytes(vec![]));
153 assert_eq!(bytes5, Bytes(vec![0x12]));
154 assert_eq!(bytes6, Bytes(vec![0x1, 0x23]));
155 }
156}