s_types_serialize/
lib.rs

1extern crate serde;
2
3use std::fmt;
4use serde::{de, Serializer, Deserializer};
5
6static CHARS: &'static[u8] = b"0123456789abcdef";
7
8fn to_hex<'a>(v: &'a mut [u8], bytes: &[u8], skip_leading_zero: bool) -> &'a str {
9	assert!(v.len() > 1 + bytes.len() * 2);
10
11	v[0] = b'0';
12	v[1] = b'x';
13
14	let mut idx = 2;
15	let first_nibble = bytes[0] >> 4;
16	if first_nibble != 0 || !skip_leading_zero {
17		v[idx] = CHARS[first_nibble as usize];
18		idx += 1;
19	}
20	v[idx] = CHARS[(bytes[0] & 0xf) as usize];
21	idx += 1;
22
23	for &byte in bytes.iter().skip(1) {
24		v[idx] = CHARS[(byte >> 4) as usize];
25		v[idx + 1] = CHARS[(byte & 0xf) as usize];
26		idx += 2;
27	}
28
29	::std::str::from_utf8(&v[0..idx]).expect("All characters are coming from CHARS")
30}
31
32/// Serializes a slice of bytes.
33pub fn serialize<S>(slice: &mut [u8], bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
34	S: Serializer,
35{
36	serializer.serialize_str(to_hex(slice, bytes, false))
37}
38
39/// Serialize a slice of bytes as uint.
40///
41/// The representation will have all leading zeros trimmed.
42pub fn serialize_uint<S>(slice: &mut [u8], bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
43	S: Serializer,
44{
45	let non_zero = bytes.iter().take_while(|b| **b == 0).count();
46	let bytes = &bytes[non_zero..];
47	if bytes.is_empty() {
48		return serializer.serialize_str("0x0");
49	}
50
51	serializer.serialize_str(to_hex(slice, bytes, true))
52}
53
54/// Expected length of bytes vector.
55#[derive(Debug, PartialEq, Eq)]
56pub enum ExpectedLen<'a> {
57	/// Exact length in bytes.
58	Exact(&'a mut [u8]),
59	/// A bytes length between (min; slice.len()].
60	Between(usize, &'a mut [u8]),
61}
62
63impl<'a> fmt::Display for ExpectedLen<'a> {
64	fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
65		match *self {
66			ExpectedLen::Exact(ref v) => write!(fmt, "length of {}", v.len() * 2),
67            ExpectedLen::Between(min, ref v) => write!(fmt, "length between ({}; {}]", min * 2, v.len() * 2),
68		}
69	}
70}
71
72/// Deserialize into vector of bytes with additional size check.
73/// Returns number of bytes written.
74pub fn deserialize_check_len<'a, 'de, D>(deserializer: D, len: ExpectedLen<'a>) -> Result<usize, D::Error> where
75	D: Deserializer<'de>,
76{
77	struct Visitor<'a> {
78		len: ExpectedLen<'a>,
79	}
80
81	impl<'a, 'b> de::Visitor<'b> for Visitor<'a> {
82		type Value = usize;
83
84		fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
85			write!(formatter, "a 0x-prefixed hex string with {}", self.len)
86		}
87
88		fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
89			if v.len() < 2  || &v[0..2] != "0x" {
90				return Err(E::custom("prefix is missing"))
91			}
92
93			let is_len_valid = match self.len {
94				ExpectedLen::Exact(ref slice) => v.len() == 2 * slice.len() + 2,
95				ExpectedLen::Between(min, ref slice) => v.len() <= 2 * slice.len() + 2 && v.len() > 2 * min + 2,
96			};
97
98			if !is_len_valid {
99				return Err(E::invalid_length(v.len() - 2, &self))
100			}
101
102			let bytes = match self.len {
103				ExpectedLen::Exact(slice) => slice,
104				ExpectedLen::Between(_, slice) => slice,
105			};
106
107			let mut modulus = v.len() % 2;
108			let mut buf = 0;
109			let mut pos = 0;
110			for (idx, byte) in v.bytes().enumerate().skip(2) {
111				buf <<= 4;
112
113				match byte {
114					b'A'...b'F' => buf |= byte - b'A' + 10,
115					b'a'...b'f' => buf |= byte - b'a' + 10,
116					b'0'...b'9' => buf |= byte - b'0',
117					b' '|b'\r'|b'\n'|b'\t' => {
118						buf >>= 4;
119						continue
120					}
121					_ => {
122						let ch = v[idx..].chars().next().unwrap();
123						return Err(E::custom(&format!("invalid hex character: {}, at {}", ch, idx)))
124					}
125				}
126
127				modulus += 1;
128				if modulus == 2 {
129					modulus = 0;
130					bytes[pos] = buf;
131					pos += 1;
132				}
133			}
134
135			Ok(pos)
136		}
137
138		fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
139			self.visit_str(&v)
140		}
141	}
142
143	deserializer.deserialize_str(Visitor { len })
144}