feat(proto): add protocol primitives
This commit is contained in:
parent
f70fd6250b
commit
aa649769d2
7 changed files with 173 additions and 0 deletions
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