Skip to main content

rusty_tarantool/tarantool/
tools.rs

1use byteorder::ReadBytesExt;
2use bytes::{Buf, BufMut, Bytes, BytesMut};
3use rmp_serde::{Deserializer, Serializer};
4use rmp::encode;
5use rmpv::decode;
6use rmpv::Value;
7use serde::{Deserialize, Serialize};
8use sha1::{Sha1, Digest};
9use std::error;
10use std::io;
11use std::io::{Cursor};
12use std::collections::HashMap;
13
14pub fn decode_serde_optional<'de, T>( data: &Option<Bytes>) -> Option<T>
15    where T:Deserialize<'de>
16{
17    data.as_ref()
18        .and_then(|meta_bytes| {
19            let res: io::Result<T> = decode_serde(Cursor::new(meta_bytes));
20            res.ok()
21        })
22}
23
24pub fn decode_serde<'de, T, R>(r: R) -> io::Result<T>
25where
26    T: Deserialize<'de>,
27    R: io::Read,
28{
29    Deserialize::deserialize(&mut Deserializer::new(r)).map_err(map_err_to_io)
30}
31
32pub fn serialize_to_buf_mut<W: io::Write, S: Serialize>(wr: &mut W, v: &S) -> io::Result<()> {
33    v.serialize(&mut Serializer::new(wr)).map_err(map_err_to_io)
34}
35
36pub fn serialize_to_vec_u8<S: Serialize>(v: &S) -> io::Result<Vec<u8>> {
37    let mut buf = Vec::new();
38    serialize_to_buf_mut(&mut buf, v)?;
39    Ok(buf)
40}
41
42pub fn serialize_one_element_map(name:String, value: Vec<u8>) -> io::Result<Vec<u8>> {
43    let mut buf = BytesMut::new();
44    let mut writer = SafeBytesMutWriter::writer(&mut buf);
45
46    encode::write_map_len(
47        &mut writer,
48        1,
49    )?;
50    encode::write_str(&mut writer, name.as_str())?;
51    io::Write::write(&mut writer, &value)?;
52    Ok(buf.to_vec())
53}
54
55pub fn serialize_array(args: &[Vec<u8>]) -> io::Result<Vec<u8>> {
56    let mut buf = BytesMut::new();
57    let mut writer = SafeBytesMutWriter::writer(&mut buf);
58
59    encode::write_array_len(
60        &mut writer,
61        args.len() as u32 ,
62    )?;
63    for arg in args {
64        io::Write::write(&mut writer, arg)?;
65    }
66    Ok(buf.to_vec())
67}
68
69pub fn map_err_to_io<E>(e: E) -> io::Error
70where
71    E: Into<Box<dyn error::Error + Send + Sync>>,
72{
73    let errr = e.into().to_string();
74    error!("Error! {:?}", errr);
75    io::Error::new(io::ErrorKind::Other, errr)
76}
77
78#[allow(dead_code)]
79pub fn make_map_err_to_io() -> io::Error {
80    error!("make Error! ");
81    io::Error::new(io::ErrorKind::Other, "Cant get key from map!")
82}
83
84pub fn parse_msgpack_map(rr: Cursor<BytesMut>) -> io::Result<HashMap<u64,Bytes>> {
85    let pos = rr.position();
86    let mut bytes_mut = rr.into_inner();
87    let positions = get_entries_positions(pos, bytes_mut.as_ref())?;
88    let mut result: HashMap<u64, Bytes> = HashMap::new();
89
90    let mut counter:usize = 0;
91    for (key, (start, end)) in positions {
92        bytes_mut.advance(start-counter);
93        let value = bytes_mut.split_to(end-start);
94        result.insert(key, value.freeze());
95        counter = end;
96    }
97
98    Ok(result)
99}
100
101fn get_entries_positions(pos: u64, inner: &[u8]) -> io::Result<Vec<(u64, (usize, usize))>> {
102    let mut r = Cursor::new(inner);
103    r.set_position(pos);
104    let mut result: Vec<(u64, (usize, usize))> = Vec::new();
105    r.read_u8()?;
106    while r.remaining() != 0 {
107        let key = decode::read_value_ref(&mut r).map_err(map_err_to_io)?;
108        let start = r.position();
109        let _value = decode::read_value_ref(&mut r).map_err(map_err_to_io)?;
110        let end = r.position();
111        result.push((key.as_u64().unwrap(), (start as usize, end as usize)));
112    }
113    Ok(result)
114}
115
116// pub fn search_key_in_msgpack_map(r: Cursor<BytesMut>, search_key: u64) -> io::Result<Bytes> {
117//     Ok(parse_msgpack_map(r)?.remove(&search_key).unwrap_or(Bytes::new()))
118// }
119
120// pub fn search_key_in_msgpack_map1(mut r: Cursor<BytesMut>, search_key: u64) -> io::Result<Bytes> {
121//     r.read_u8()?;
122//     if r.remaining() == 0 {
123//         Ok(Bytes::new())
124//     } else {
125//         while r.remaining() != 0 {
126//             let key = decode::read_value(&mut r).map_err(map_err_to_io)?;
127//             match key {
128//                 Value::Integer(k) if k.is_u64() && k.as_u64().unwrap() == search_key => {
129//                     let pos = r.position();
130//                     let mut res_buf = r.into_inner();
131//                     //                    res_buf.split_to(pos as usize);
132//                     res_buf.advance(pos as usize);
133//                     return Ok(res_buf.freeze());
134//                 }
135//                 _ => {}
136//             }
137//         }
138//         Err(io::Error::new(
139//             io::ErrorKind::Other,
140//             "Incorrect headers msg pack type!",
141//         ))
142//     }
143// }
144
145pub fn get_map_value(map: &[(Value, Value)], key: u64) -> io::Result<u64> {
146    map.iter()
147        .filter_map(|row| match row {
148            (Value::Integer(row_key), Value::Integer(val))
149                if row_key.as_u64() == Some(key) && val.is_u64() =>
150            {
151                val.as_u64()
152            }
153            _ => None,
154        })
155        .next()
156        .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Not found header !"))
157}
158
159#[allow(dead_code)]
160pub fn transform_u32_to_array_of_u8(x: u32) -> [u8; 4] {
161    let b1: u8 = ((x >> 24) & 0xff) as u8;
162    let b2: u8 = ((x >> 16) & 0xff) as u8;
163    let b3: u8 = ((x >> 8) & 0xff) as u8;
164    let b4: u8 = (x & 0xff) as u8;
165    [b1, b2, b3, b4]
166}
167
168pub fn write_u32_to_slice(buf: &mut [u8], x: u32) {
169    buf[0] = ((x >> 24) & 0xff) as u8;
170    buf[1] = ((x >> 16) & 0xff) as u8;
171    buf[2] = ((x >> 8) & 0xff) as u8;
172    buf[3] = (x & 0xff) as u8;
173}
174
175pub fn make_auth_digest(salt_bytes: Vec<u8>, password: &[u8]) -> io::Result<[u8; 20]> {
176    let mut sha1 = Sha1::new();
177    sha1.update(password);
178    let digest1 = sha1.finalize();
179    let mut sha1 = Sha1::new();
180
181    sha1.update(&digest1);
182    let digest2 = sha1.finalize();
183
184    let mut sha1 = Sha1::new();
185    let salt_str = String::from_utf8(salt_bytes).map_err(map_err_to_io)?;
186
187    let decoded_salt = &base64::decode(&salt_str.trim()).map_err(map_err_to_io)?[..20];
188    sha1.update(&decoded_salt);
189    sha1.update(&digest2);
190    let digest3 = sha1.finalize();
191
192    let mut digest4: [u8; 20] = [0; 20];
193
194    for (i, digest1_b) in digest1.iter().enumerate() {
195        digest4[i] = digest1_b ^ digest3[i];
196    }
197    Ok(digest4)
198}
199
200//safe buf mut writer
201
202#[derive(Debug)]
203pub struct SafeBytesMutWriter<'a> {
204    buf: &'a mut BytesMut,
205}
206
207impl<'a> SafeBytesMutWriter<'a> {
208    pub fn writer(buf: &'a mut BytesMut) -> SafeBytesMutWriter {
209        Self { buf }
210    }
211}
212
213impl<'a> io::Write for SafeBytesMutWriter<'a> {
214    fn write(&mut self, src: &[u8]) -> io::Result<usize> {
215        self.buf.reserve(src.len());
216        self.buf.put(src);
217        Ok(src.len())
218    }
219
220    fn flush(&mut self) -> io::Result<()> {
221        Ok(())
222    }
223}