1#[cfg(test)]
24mod tests;
25
26use crate::error::Error;
27use crate::put_bytes::PutBytes;
28
29pub trait ToBytes {
34 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error>;
40}
41
42impl ToBytes for bool {
43 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
44 let val = if *self { 1u8 } else { 0u8 };
45
46 ToBytes::to_bytes(&val, target)
47 }
48}
49
50macro_rules! impl_to_bytes_for_primitive {
51 ($type:ty) => {
52 impl ToBytes for $type {
53 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
54 let n = target
55 .put_bytes(&self.to_be_bytes())
56 .map(|()| std::mem::size_of::<$type>())?;
57 Ok(n)
58 }
59 }
60 };
61}
62
63impl_to_bytes_for_primitive!(i8);
64impl_to_bytes_for_primitive!(i16);
65impl_to_bytes_for_primitive!(i32);
66impl_to_bytes_for_primitive!(i64);
67impl_to_bytes_for_primitive!(u8);
68impl_to_bytes_for_primitive!(u16);
69impl_to_bytes_for_primitive!(u32);
70impl_to_bytes_for_primitive!(u64);
71impl_to_bytes_for_primitive!(f32);
72impl_to_bytes_for_primitive!(f64);
73
74impl ToBytes for usize {
75 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
76 ToBytes::to_bytes(&(*self as u64), target)
77 }
78}
79
80impl ToBytes for char {
81 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
82 ToBytes::to_bytes(&(*self as u32), target)
83 }
84}
85
86impl<TB: ToBytes, const COUNT: usize> ToBytes for [TB; COUNT] {
87 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
88 let mut n = 0;
89
90 for b in self.iter().take(COUNT) {
91 n += ToBytes::to_bytes(b, target)?;
92 }
93
94 Ok(n)
95 }
96}
97
98impl<TB: ToBytes> ToBytes for &[TB] {
99 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
100 let mut n = self.len().to_bytes(target)?;
101
102 for i in 0..self.len() {
103 n += self[i].to_bytes(target)?;
104 }
105
106 Ok(n)
107 }
108}
109
110impl<TB: ToBytes> ToBytes for Vec<TB> {
111 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
112 ToBytes::to_bytes(&self.as_slice(), target)
113 }
114}
115
116impl ToBytes for String {
117 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
118 ToBytes::to_bytes(&self.as_str(), target)
119 }
120}
121
122impl ToBytes for &str {
123 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
124 self.as_bytes().to_bytes(target)
125 }
126}
127
128impl<T: ToBytes> ToBytes for Option<T> {
129 fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
130 match self {
131 Some(val) => Ok(ToBytes::to_bytes(&1u8, target)? + ToBytes::to_bytes(val, target)?),
132 None => ToBytes::to_bytes(&0u8, target),
133 }
134 }
135}
136
137impl ToBytes for () {
138 fn to_bytes<PB: PutBytes>(&self, _target: &mut PB) -> Result<usize, Error> {
139 Ok(0)
140 }
141}