midnight_base_crypto/
repr.rs1pub use derive::BinaryHashRepr;
18use serialize::VecExt;
19use std::io;
20
21pub trait MemWrite<T> {
23 fn write(&mut self, buf: &[T]);
25}
26
27impl<T: Copy> MemWrite<T> for Vec<T> {
28 fn write(&mut self, buf: &[T]) {
29 self.extend(buf);
30 }
31}
32
33impl<T, W: MemWrite<T>> MemWrite<T> for &mut W {
34 fn write(&mut self, buf: &[T]) {
35 W::write(self, buf);
36 }
37}
38
39pub struct IoWrite<W: MemWrite<u8>>(pub W);
41
42impl<W: MemWrite<u8>> io::Write for IoWrite<W> {
43 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
44 self.0.write(buf);
45 Ok(buf.len())
46 }
47 fn flush(&mut self) -> io::Result<()> {
48 Ok(())
49 }
50}
51
52pub trait BinaryHashRepr {
54 fn binary_repr<W: MemWrite<u8>>(&self, writer: &mut W);
56 fn binary_len(&self) -> usize;
58 fn binary_vec(&self) -> Vec<u8> {
60 let mut res = Vec::with_bounded_capacity(self.binary_len());
61 self.binary_repr(&mut res);
62 res
63 }
64}
65
66impl BinaryHashRepr for [u8] {
67 fn binary_repr<W: MemWrite<u8>>(&self, writer: &mut W) {
68 writer.write(self);
69 }
70 fn binary_len(&self) -> usize {
71 self.len()
72 }
73}
74
75impl<const N: usize> BinaryHashRepr for [u8; N] {
76 fn binary_repr<W: MemWrite<u8>>(&self, writer: &mut W) {
77 writer.write(self)
78 }
79 fn binary_len(&self) -> usize {
80 N
81 }
82}
83
84macro_rules! integer_hash_repr {
85 ($($ty:ty),*) => {
86 $(
87 impl BinaryHashRepr for $ty {
88 fn binary_repr<W: MemWrite<u8>>(&self, writer: &mut W) {
89 writer.write(&self.to_le_bytes());
90 }
91 fn binary_len(&self) -> usize {
92 <$ty>::BITS as usize / 8
93 }
94 }
95 )*
96 }
97}
98
99macro_rules! tuple_repr {
100 ($head:ident$(, $tail:ident)*) => {
101 #[allow(unused_parens, non_snake_case)]
102 impl<$head: BinaryHashRepr$(, $tail: BinaryHashRepr)*> BinaryHashRepr for ($head, $($tail),*) {
103 fn binary_repr<W: MemWrite<u8>>(&self, writer: &mut W) {
104 let ($head, $($tail),*) = self;
105 $head.binary_repr(writer);
106 $($tail.binary_repr(writer);)*
107 }
108 fn binary_len(&self) -> usize {
109 let ($head, $($tail),*) = self;
110 $head.binary_len() $(+ $tail.binary_len())*
111 }
112 }
113 tuple_repr!($($tail),*);
114 };
115 () => {
116 impl BinaryHashRepr for () {
117 fn binary_repr<W: MemWrite<u8>>(&self, _: &mut W) {
118 }
119 fn binary_len(&self) -> usize {
120 0
121 }
122 }
123 };
124}
125
126tuple_repr!(A, B, C, D, E, F, G, H, I, J, K, L);
127
128integer_hash_repr!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
129
130impl BinaryHashRepr for bool {
131 fn binary_repr<W: MemWrite<u8>>(&self, writer: &mut W) {
132 writer.write(&[*self as u8]);
133 }
134 fn binary_len(&self) -> usize {
135 1
136 }
137}