ratman_types/
lib.rs

1// SPDX-FileCopyrightText: 2019-2022 Katharina Fey <kookie@spacekookie.de>
2//
3// SPDX-License-Identifier: AGPL-3.0-or-later WITH LicenseRef-AppStore
4
5//! API encoding types for Ratman
6
7mod error;
8
9#[cfg(feature = "proto")]
10mod proto {
11    include!(concat!(env!("OUT_DIR"), "/proto_gen/mod.rs"));
12}
13
14#[cfg(feature = "proto")]
15pub mod api;
16
17mod message;
18mod timepair;
19
20pub use message::{Message, Recipient};
21pub use timepair::TimePair;
22
23pub use error::{Error, Result};
24pub use ratman_identity::Identity;
25
26use async_std::{
27    io::{Read, Write},
28    prelude::*,
29};
30use byteorder::{BigEndian, ByteOrder};
31
32#[cfg(feature = "proto")]
33use {api::ApiMessage, protobuf::Message as ProtoMessage};
34
35/// First write the length as big-endian u64, then write the provided buffer
36pub async fn write_with_length<T: Write + Unpin>(t: &mut T, buf: &Vec<u8>) -> Result<usize> {
37    let mut len = vec![0; 8];
38    BigEndian::write_u64(&mut len, buf.len() as u64);
39    t.write_all(len.as_slice()).await?;
40    t.write_all(buf.as_slice()).await?;
41    Ok(len.len() + buf.len())
42}
43
44/// First read a big-endian u64, then read the number of bytes
45pub async fn read_with_length<T: Read + Unpin>(r: &mut T) -> Result<Vec<u8>> {
46    let mut len_buf = vec![0; 8];
47    r.read_exact(&mut len_buf).await?;
48    let len = BigEndian::read_u64(&len_buf);
49
50    let mut vec = vec![0; len as usize]; // FIXME: this might break on 32bit systems
51    r.read_exact(&mut vec).await?;
52    Ok(vec)
53}
54
55/// Parse a single message from a reader stream
56#[cfg(feature = "proto")]
57pub async fn parse_message<R: Read + Unpin>(r: &mut R) -> Result<ApiMessage> {
58    let vec = read_with_length(r).await?;
59    decode_message(&vec)
60}
61
62#[cfg(feature = "proto")]
63#[inline]
64pub fn decode_message(vec: &Vec<u8>) -> Result<ApiMessage> {
65    Ok(ApiMessage::parse_from_bytes(vec)?)
66}
67
68/// Encode an ApiMessage into a binary payload you can then pass to
69/// `write_with_length`
70#[cfg(feature = "proto")]
71#[inline]
72pub fn encode_message(msg: ApiMessage) -> Result<Vec<u8>> {
73    let mut buf = vec![];
74    msg.write_to_vec(&mut buf)?;
75    Ok(buf)
76}