fc_rpc_v2_types/
bytes.rs

1// This file is part of Frontier.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19use std::{fmt, ops};
20
21#[derive(Clone, Default, Eq, PartialEq, Hash)]
22pub struct Bytes(pub Vec<u8>);
23
24impl Bytes {
25	pub fn new(bytes: Vec<u8>) -> Self {
26		Self(bytes)
27	}
28
29	pub fn into_vec(self) -> Vec<u8> {
30		self.0
31	}
32}
33
34impl fmt::Debug for Bytes {
35	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36		fmt::LowerHex::fmt(self, f)
37	}
38}
39
40impl fmt::Display for Bytes {
41	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42		fmt::LowerHex::fmt(self, f)
43	}
44}
45
46impl fmt::LowerHex for Bytes {
47	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48		f.pad(&const_hex::encode_prefixed(self.as_ref()))
49	}
50}
51
52impl fmt::UpperHex for Bytes {
53	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54		f.pad(&const_hex::encode_upper_prefixed(self.as_ref()))
55	}
56}
57
58impl ops::Deref for Bytes {
59	type Target = [u8];
60
61	#[inline]
62	fn deref(&self) -> &Self::Target {
63		&self.0
64	}
65}
66
67impl ops::DerefMut for Bytes {
68	#[inline]
69	fn deref_mut(&mut self) -> &mut Self::Target {
70		&mut self.0
71	}
72}
73
74impl AsRef<[u8]> for Bytes {
75	#[inline]
76	fn as_ref(&self) -> &[u8] {
77		self.0.as_ref()
78	}
79}
80
81impl From<Vec<u8>> for Bytes {
82	fn from(bytes: Vec<u8>) -> Bytes {
83		Bytes(bytes)
84	}
85}
86
87impl From<Bytes> for Vec<u8> {
88	fn from(bytes: Bytes) -> Vec<u8> {
89		bytes.0
90	}
91}
92
93impl serde::Serialize for Bytes {
94	#[inline]
95	fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
96		if serializer.is_human_readable() {
97			const_hex::serialize(self, serializer)
98		} else {
99			serializer.serialize_bytes(self.as_ref())
100		}
101	}
102}
103
104impl<'de> serde::Deserialize<'de> for Bytes {
105	#[inline]
106	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
107	where
108		D: serde::Deserializer<'de>,
109	{
110		use serde::de;
111
112		struct BytesVisitor;
113
114		impl<'de> de::Visitor<'de> for BytesVisitor {
115			type Value = Bytes;
116
117			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
118				formatter.write_str(
119					"a variable number of bytes represented as a hex string, an array of u8, or raw bytes",
120				)
121			}
122
123			fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
124			where
125				E: de::Error,
126			{
127				if v.is_empty() {
128					return Err(de::Error::invalid_value(
129						de::Unexpected::Str(v),
130						&"a valid hex string",
131					));
132				}
133
134				const_hex::decode(v)
135					.map_err(|_| {
136						de::Error::invalid_value(de::Unexpected::Str(v), &"a valid hex string")
137					})
138					.map(From::from)
139			}
140
141			fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
142			where
143				E: de::Error,
144			{
145				self.visit_str(value.as_ref())
146			}
147
148			fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
149				Ok(Bytes::from(v.to_vec()))
150			}
151
152			fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
153				Ok(Bytes::from(v))
154			}
155
156			fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
157				let mut bytes = Vec::with_capacity(seq.size_hint().unwrap_or(0));
158
159				while let Some(byte) = seq.next_element()? {
160					bytes.push(byte);
161				}
162
163				Ok(Bytes::from(bytes))
164			}
165		}
166
167		if deserializer.is_human_readable() {
168			deserializer.deserialize_any(BytesVisitor)
169		} else {
170			deserializer.deserialize_byte_buf(BytesVisitor)
171		}
172	}
173}
174
175#[cfg(test)]
176mod tests {
177	use super::*;
178
179	#[test]
180	fn bytes_serialize() {
181		let bytes = const_hex::decode("0123456789abcdef").unwrap();
182		let bytes = Bytes::new(bytes);
183		let serialized = serde_json::to_string(&bytes).unwrap();
184		assert_eq!(serialized, r#""0x0123456789abcdef""#);
185	}
186
187	#[test]
188	fn bytes_deserialize() {
189		let bytes0: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""∀∂""#);
190		let bytes1: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""""#);
191		let bytes2: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""0x123""#);
192		let bytes3: Result<Bytes, serde_json::Error> = serde_json::from_str(r#""0xgg""#);
193
194		let bytes4: Bytes = serde_json::from_str(r#""0x""#).unwrap();
195		let bytes5: Bytes = serde_json::from_str(r#""0x12""#).unwrap();
196		let bytes6: Bytes = serde_json::from_str(r#""0x0123""#).unwrap();
197
198		assert!(bytes0.is_err());
199		assert!(bytes1.is_err());
200		assert!(bytes2.is_err());
201		assert!(bytes3.is_err());
202		assert_eq!(bytes4, Bytes(vec![]));
203		assert_eq!(bytes5, Bytes(vec![0x12]));
204		assert_eq!(bytes6, Bytes(vec![0x1, 0x23]));
205	}
206}