1use std::io::{Read, Write};
2
3use crate::error::{IgniteError, IgniteResult};
4use crate::protocol::*;
5use crate::protocol::{read_u8, TypeCode};
6
7use crate::{Enum, ReadableType, WritableType};
8use std::io;
9
10macro_rules! write_type {
15 ($t:ty, $code:path, $write_fn:ident, $size:expr) => {
16 impl WritableType for $t {
17 fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
18 write_u8(writer, $code as u8)?;
19 $write_fn(writer, *self)?;
20 Ok(())
21 }
22
23 fn size(&self) -> usize {
24 $size + 1 }
26 }
27 };
28}
29
30write_type!(u8, TypeCode::Byte, write_u8, 1);
31write_type!(u16, TypeCode::Char, write_u16, 2);
32write_type!(i16, TypeCode::Short, write_i16, 2);
33write_type!(i32, TypeCode::Int, write_i32, 4);
34write_type!(i64, TypeCode::Long, write_i64, 8);
35write_type!(f32, TypeCode::Float, write_f32, 4);
36write_type!(f64, TypeCode::Double, write_f64, 8);
37write_type!(bool, TypeCode::Bool, write_bool, 1);
38write_type!(Enum, TypeCode::Enum, write_enum, 8);
39
40impl WritableType for String {
41 fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
42 write_u8(writer, TypeCode::String as u8)?;
43 write_string(writer, self)?;
44 Ok(())
45 }
46
47 fn size(&self) -> usize {
48 self.len() + 1 + 4 }
50}
51
52macro_rules! read_type {
53 ($t:ty, $read_fn:ident) => {
54 impl ReadableType for $t {
55 fn read_unwrapped(
56 type_code: TypeCode,
57 reader: &mut impl Read,
58 ) -> IgniteResult<Option<Self>> {
59 let value: Option<Self> = match type_code {
60 TypeCode::Null => None,
61 _ => Some($read_fn(reader)?),
62 };
63 Ok(value)
64 }
65 }
66 };
67}
68
69read_type!(u8, read_u8);
70read_type!(u16, read_u16);
71read_type!(i16, read_i16);
72read_type!(i32, read_i32);
73read_type!(i64, read_i64);
74read_type!(f32, read_f32);
75read_type!(f64, read_f64);
76read_type!(bool, read_bool);
77read_type!(String, read_string);
78read_type!(Enum, read_enum);
79
80macro_rules! write_primitive_arr {
81 ($t:ty, $code:path, $write_fn:ident, $size:expr) => {
82 impl WritableType for Vec<$t> {
83 fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
84 write_u8(writer, $code as u8)?;
85 write_i32(writer, self.len() as i32)?; for el in self {
87 $write_fn(writer, *el)?;
88 }
89 Ok(())
90 }
91
92 fn size(&self) -> usize {
93 $size * self.len() + 4 + 1 }
95 }
96 };
97}
98
99write_primitive_arr!(u8, TypeCode::ArrByte, write_u8, 1);
100write_primitive_arr!(i16, TypeCode::ArrShort, write_i16, 2);
101write_primitive_arr!(i32, TypeCode::ArrInt, write_i32, 4);
102write_primitive_arr!(i64, TypeCode::ArrLong, write_i64, 8);
103write_primitive_arr!(f32, TypeCode::ArrFloat, write_f32, 4);
104write_primitive_arr!(f64, TypeCode::ArrDouble, write_f64, 8);
105write_primitive_arr!(bool, TypeCode::ArrBool, write_bool, 1);
106write_primitive_arr!(u16, TypeCode::ArrChar, write_u16, 2);
107
108macro_rules! read_primitive_arr {
109 ($t:ty, $read_fn:ident) => {
110 impl ReadableType for Vec<$t> {
111 fn read_unwrapped(
112 type_code: TypeCode,
113 reader: &mut impl Read,
114 ) -> IgniteResult<Option<Self>> {
115 let value: Option<Self> = match type_code {
116 TypeCode::Null => None,
117 _ => Some(read_primitive_arr(reader, $read_fn)?),
118 };
119 Ok(value)
120 }
121 }
122 };
123}
124
125read_primitive_arr!(u8, read_u8);
126read_primitive_arr!(u16, read_u16);
127read_primitive_arr!(i16, read_i16);
128read_primitive_arr!(i32, read_i32);
129read_primitive_arr!(i64, read_i64);
130read_primitive_arr!(f32, read_f32);
131read_primitive_arr!(f64, read_f64);
132read_primitive_arr!(bool, read_bool);
133
134impl<T: WritableType + ReadableType> WritableType for Vec<Option<T>> {
136 fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
137 write_u8(writer, TypeCode::ArrObj as u8)?;
138 write_i32(writer, -1)?; write_i32(writer, self.len() as i32)?; for item in self {
141 match item {
142 None => write_u8(writer, TypeCode::Null as u8)?,
143 Some(value) => value.write(writer)?,
144 }
145 }
146 Ok(())
147 }
148
149 fn size(&self) -> usize {
150 let mut items_size: usize = 0;
151 for item in self {
152 match item {
153 None => items_size += 1, Some(value) => items_size += value.size(),
155 }
156 }
157 items_size + 1 + 4 + 4 }
159}
160
161impl<T: WritableType + ReadableType> ReadableType for Vec<Option<T>> {
162 fn read_unwrapped(type_code: TypeCode, reader: &mut impl Read) -> IgniteResult<Option<Self>> {
163 match type_code {
164 TypeCode::Null => Ok(None),
165 TypeCode::ArrObj => {
166 read_i32(reader)?; let len = read_i32(reader)?;
168 let mut data: Vec<Option<T>> = Vec::with_capacity(len as usize);
169 for _ in 0..len {
170 let item = T::read(reader)?;
171 data.push(item);
172 }
173 Ok(Some(data))
174 }
175 TypeCode::Collection => {
176 let len = read_i32(reader)?;
177 read_i8(reader)?; let mut data: Vec<Option<T>> = Vec::with_capacity(len as usize);
179 for _ in 0..len {
180 let item = T::read(reader)?;
181 data.push(item);
182 }
183 Ok(Some(data))
184 }
185 _ => Err(IgniteError::from("Expected Array or Collection!")),
186 }
187 }
188}
189
190impl<T: WritableType> WritableType for Option<T> {
191 fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
192 match self {
193 None => write_u8(writer, TypeCode::Null as u8),
194 Some(inner) => inner.write(writer),
195 }
196 }
197
198 fn size(&self) -> usize {
199 match self {
200 None => 1, Some(inner) => inner.size(),
202 }
203 }
204}
205
206impl<T: ReadableType> ReadableType for Option<T> {
207 fn read_unwrapped(type_code: TypeCode, reader: &mut impl Read) -> IgniteResult<Option<Self>> {
208 let inner_op = T::read_unwrapped(type_code, reader)?;
209 match inner_op {
210 None => Ok(None),
211 Some(inner) => Ok(Some(Some(inner))),
212 }
213 }
214}