feat(proto): add protocol primitives
This commit is contained in:
parent
f70fd6250b
commit
aa649769d2
7 changed files with 173 additions and 0 deletions
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod message;
|
||||||
1
proto/src/message/mod.rs
Normal file
1
proto/src/message/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod primitive;
|
||||||
7
proto/src/message/primitive/config.rs
Normal file
7
proto/src/message/primitive/config.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
use bincode::config::{BigEndian, Configuration, Fixint};
|
||||||
|
|
||||||
|
pub fn pg_proto_config() -> Configuration<BigEndian, Fixint> {
|
||||||
|
bincode::config::standard()
|
||||||
|
.with_big_endian()
|
||||||
|
.with_fixed_int_encoding()
|
||||||
|
}
|
||||||
22
proto/src/message/primitive/data.rs
Normal file
22
proto/src/message/primitive/data.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
use crate::message::primitive::config::pg_proto_config;
|
||||||
|
use bincode::{Decode, Encode};
|
||||||
|
|
||||||
|
pub trait MessageData: Sized {
|
||||||
|
fn deserialize(data: &[u8]) -> anyhow::Result<Self>;
|
||||||
|
fn serialize(&self) -> anyhow::Result<Vec<u8>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MessageData for T
|
||||||
|
where
|
||||||
|
T: Encode + Decode,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn deserialize(data: &[u8]) -> anyhow::Result<Self> {
|
||||||
|
Ok(bincode::decode_from_slice(data, pg_proto_config())?.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn serialize(&self) -> anyhow::Result<Vec<u8>> {
|
||||||
|
Ok(bincode::encode_to_vec(self, pg_proto_config())?)
|
||||||
|
}
|
||||||
|
}
|
||||||
4
proto/src/message/primitive/mod.rs
Normal file
4
proto/src/message/primitive/mod.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
pub(crate) mod config;
|
||||||
|
pub(crate) mod data;
|
||||||
|
pub mod pglist;
|
||||||
|
pub mod pgstring;
|
||||||
84
proto/src/message/primitive/pglist.rs
Normal file
84
proto/src/message/primitive/pglist.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
use bincode::de::Decoder;
|
||||||
|
use bincode::enc::Encoder;
|
||||||
|
use bincode::error::{DecodeError, EncodeError};
|
||||||
|
use bincode::{BorrowDecode, Decode, Encode};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, BorrowDecode)]
|
||||||
|
pub struct PgList<T, U>(Vec<T>, PhantomData<U>);
|
||||||
|
|
||||||
|
impl<T, U> PgList<T, U> {
|
||||||
|
pub fn as_slice(&self) -> &[T] {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, U> From<PgList<T, U>> for Vec<T> {
|
||||||
|
fn from(pg_list: PgList<T, U>) -> Self {
|
||||||
|
pg_list.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, U> From<Vec<T>> for PgList<T, U> {
|
||||||
|
fn from(list: Vec<T>) -> Self {
|
||||||
|
PgList(list, PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Encode for PgList<T, i16>
|
||||||
|
where
|
||||||
|
T: Encode,
|
||||||
|
{
|
||||||
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
let length = self.0.len() as i16;
|
||||||
|
length.encode(encoder)?;
|
||||||
|
for item in &self.0 {
|
||||||
|
item.encode(encoder)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Decode for PgList<T, i16>
|
||||||
|
where
|
||||||
|
T: Decode,
|
||||||
|
{
|
||||||
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let length = i16::decode(decoder)?;
|
||||||
|
let mut list = Vec::new();
|
||||||
|
for _ in 0..length {
|
||||||
|
list.push(T::decode(decoder)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(PgList(list, PhantomData))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Encode for PgList<T, i32>
|
||||||
|
where
|
||||||
|
T: Encode,
|
||||||
|
{
|
||||||
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
let length = self.0.len() as i32;
|
||||||
|
length.encode(encoder)?;
|
||||||
|
for item in &self.0 {
|
||||||
|
item.encode(encoder)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Decode for PgList<T, i32>
|
||||||
|
where
|
||||||
|
T: Decode,
|
||||||
|
{
|
||||||
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let length = i32::decode(decoder)?;
|
||||||
|
let mut list = Vec::new();
|
||||||
|
for _ in 0..length {
|
||||||
|
list.push(T::decode(decoder)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(PgList(list, PhantomData))
|
||||||
|
}
|
||||||
|
}
|
||||||
54
proto/src/message/primitive/pgstring.rs
Normal file
54
proto/src/message/primitive/pgstring.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
use bincode::de::Decoder;
|
||||||
|
use bincode::enc::write::Writer;
|
||||||
|
use bincode::enc::Encoder;
|
||||||
|
use bincode::error::{DecodeError, EncodeError};
|
||||||
|
use bincode::{BorrowDecode, Decode, Encode};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, BorrowDecode)]
|
||||||
|
pub struct PgString(String);
|
||||||
|
|
||||||
|
impl PgString {
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for PgString {
|
||||||
|
fn from(string: &str) -> Self {
|
||||||
|
PgString(string.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PgString> for String {
|
||||||
|
fn from(pg_string: PgString) -> Self {
|
||||||
|
pg_string.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for PgString {
|
||||||
|
fn from(string: String) -> Self {
|
||||||
|
PgString(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encode for PgString {
|
||||||
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
||||||
|
encoder.writer().write(self.0.as_bytes())?;
|
||||||
|
encoder.writer().write(b"\0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decode for PgString {
|
||||||
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
||||||
|
let mut string = String::new();
|
||||||
|
loop {
|
||||||
|
let byte = u8::decode(decoder)?;
|
||||||
|
if byte == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
string.push(byte as char);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(PgString(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue