feat(users/Profpatsch/netencode): add dec::{Text,Binary,OneOf}
`Text` and `Binary` should be self-explaining, they just match on the primitive and throw an error otherwise. OneOf is cool, because it allows the user to match on the result type of decoding `inner`, and give a list of values that should be allowed as the result type (the associated type `A` in the `Decoder` trait). Change-Id: Ia252e25194610555c17c37640a96953142f0a165 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2498 Tested-by: BuildkiteCI Reviewed-by: Profpatsch <mail@profpatsch.de>
This commit is contained in:
parent
8ff77f0b9f
commit
fd0d0764ec
1 changed files with 60 additions and 6 deletions
|
@ -3,6 +3,7 @@ extern crate exec_helpers;
|
|||
|
||||
use std::collections::HashMap;
|
||||
use std::io::{Write, Read};
|
||||
use std::fmt::{Display, Debug};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum T {
|
||||
|
@ -21,6 +22,7 @@ pub enum T {
|
|||
// Text
|
||||
// TODO: make into &str
|
||||
Text(String),
|
||||
// TODO: rename to Bytes
|
||||
Binary(Vec<u8>),
|
||||
// Tags
|
||||
// TODO: make into &str
|
||||
|
@ -31,7 +33,7 @@ pub enum T {
|
|||
}
|
||||
|
||||
impl T {
|
||||
fn to_u<'a>(&'a self) -> U<'a> {
|
||||
pub fn to_u<'a>(&'a self) -> U<'a> {
|
||||
match self {
|
||||
T::Unit => U::Unit,
|
||||
T::N1(b) => U::N1(*b),
|
||||
|
@ -649,6 +651,32 @@ pub mod dec {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Text;
|
||||
// TODO: rename to Bytes
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Binary;
|
||||
|
||||
impl<'a> Decoder<'a> for Text {
|
||||
type A = &'a str;
|
||||
fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> {
|
||||
match u {
|
||||
U::Text(t) => Ok(t),
|
||||
other => Err(DecodeError(format!("Cannot decode {:?} into Text", other))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Decoder<'a> for Binary {
|
||||
type A = &'a [u8];
|
||||
fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> {
|
||||
match u {
|
||||
U::Binary(b) => Ok(b),
|
||||
other => Err(DecodeError(format!("Cannot decode {:?} into Binary", other))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ScalarAsBytes;
|
||||
|
||||
|
@ -672,7 +700,9 @@ pub mod dec {
|
|||
#[derive(Clone, Copy)]
|
||||
pub struct Record<T>(pub T);
|
||||
|
||||
impl<'a, Inner: Decoder<'a>> Decoder<'a> for Record<Inner> {
|
||||
impl<'a, Inner> Decoder<'a> for Record<Inner>
|
||||
where Inner: Decoder<'a>
|
||||
{
|
||||
type A = HashMap<&'a str, Inner::A>;
|
||||
fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> {
|
||||
match u {
|
||||
|
@ -687,14 +717,16 @@ pub mod dec {
|
|||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RecordDot<'a, T> {
|
||||
field: &'a str,
|
||||
inner: T
|
||||
pub field: &'a str,
|
||||
pub inner: T
|
||||
}
|
||||
|
||||
impl <'a, Inner: Decoder<'a> + Copy> Decoder<'a> for RecordDot<'_, Inner> {
|
||||
impl <'a, Inner> Decoder<'a> for RecordDot<'_, Inner>
|
||||
where Inner: Decoder<'a> + Clone
|
||||
{
|
||||
type A = Inner::A;
|
||||
fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> {
|
||||
match Record(self.inner).dec(u) {
|
||||
match Record(self.inner.clone()).dec(u) {
|
||||
Ok(mut map) => match map.remove(self.field) {
|
||||
Some(inner) => Ok(inner),
|
||||
None => Err(DecodeError(format!("Cannot find `{}` in record map", self.field))),
|
||||
|
@ -704,6 +736,28 @@ pub mod dec {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct OneOf<T, A>{
|
||||
pub inner: T,
|
||||
pub list: Vec<A>,
|
||||
}
|
||||
|
||||
impl <'a, Inner> Decoder<'a> for OneOf<Inner, Inner::A>
|
||||
where Inner: Decoder<'a>,
|
||||
Inner::A: Display + Debug + PartialEq
|
||||
{
|
||||
type A = Inner::A;
|
||||
fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> {
|
||||
match self.inner.dec(u) {
|
||||
Ok(inner) => match self.list.iter().any(|x| x.eq(&inner)) {
|
||||
true => Ok(inner),
|
||||
false => Err(DecodeError(format!("{} is not one of {:?}", inner, self.list)))
|
||||
},
|
||||
Err(err) => Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn dec_u(b: &[u8]) -> Result<U, DecodeError> {
|
||||
match parse::u_u(b) {
|
||||
Ok((b"", u)) => Ok(u),
|
||||
|
|
Loading…
Reference in a new issue