feat: clean up errors

This commit is contained in:
rvcas 2022-06-04 14:01:45 -04:00
parent 377c5c206c
commit 1ecd47a361
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
15 changed files with 294 additions and 204 deletions

5
Cargo.lock generated
View File

@ -89,6 +89,10 @@ dependencies = [
[[package]] [[package]]
name = "flat" name = "flat"
version = "0.0.0" version = "0.0.0"
dependencies = [
"anyhow",
"thiserror",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
@ -289,7 +293,6 @@ checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
name = "uplc" name = "uplc"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow",
"combine", "combine",
"flat", "flat",
"hex", "hex",

View File

@ -6,3 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
anyhow = "1.0.57"
thiserror = "1.0.31"

View File

@ -1,11 +1,17 @@
use crate::{decoder::Decoder, filler::Filler}; mod decoder;
mod error;
use crate::filler::Filler;
pub use decoder::Decoder;
pub use error::Error;
pub trait Decode<'b>: Sized { pub trait Decode<'b>: Sized {
fn decode(d: &mut Decoder) -> Result<Self, String>; fn decode(d: &mut Decoder) -> Result<Self, Error>;
} }
impl Decode<'_> for Filler { impl Decode<'_> for Filler {
fn decode(d: &mut Decoder) -> Result<Filler, String> { fn decode(d: &mut Decoder) -> Result<Filler, Error> {
d.filler()?; d.filler()?;
Ok(Filler::FillerEnd) Ok(Filler::FillerEnd)
@ -13,43 +19,43 @@ impl Decode<'_> for Filler {
} }
impl Decode<'_> for Vec<u8> { impl Decode<'_> for Vec<u8> {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, Error> {
d.bytes() d.bytes()
} }
} }
impl Decode<'_> for u8 { impl Decode<'_> for u8 {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, Error> {
d.u8() d.u8()
} }
} }
impl Decode<'_> for isize { impl Decode<'_> for isize {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, Error> {
d.integer() d.integer()
} }
} }
impl Decode<'_> for usize { impl Decode<'_> for usize {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, Error> {
d.word() d.word()
} }
} }
impl Decode<'_> for char { impl Decode<'_> for char {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, Error> {
d.char() d.char()
} }
} }
impl Decode<'_> for String { impl Decode<'_> for String {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, Error> {
d.utf8() d.utf8()
} }
} }
impl Decode<'_> for bool { impl Decode<'_> for bool {
fn decode(d: &mut Decoder) -> Result<bool, String> { fn decode(d: &mut Decoder) -> Result<bool, Error> {
d.bool() d.bool()
} }
} }

View File

@ -1,5 +1,7 @@
use crate::{decode::Decode, zigzag}; use crate::{decode::Decode, zigzag};
use super::Error;
pub struct Decoder<'b> { pub struct Decoder<'b> {
buffer: &'b [u8], buffer: &'b [u8],
used_bits: i64, used_bits: i64,
@ -15,35 +17,38 @@ impl<'b> Decoder<'b> {
} }
} }
pub fn decode<T: Decode<'b>>(&mut self) -> Result<T, String> { /// Encode any type that implements [`Decode`].
pub fn decode<T: Decode<'b>>(&mut self) -> Result<T, Error> {
T::decode(self) T::decode(self)
} }
pub fn integer(&mut self) -> Result<isize, String> { pub fn integer(&mut self) -> Result<isize, Error> {
Ok(zigzag::to_isize(self.word()?)) Ok(zigzag::to_isize(self.word()?))
} }
pub fn bool(&mut self) -> Result<bool, String> { pub fn bool(&mut self) -> Result<bool, Error> {
let current_byte = self.buffer[self.pos]; let current_byte = self.buffer[self.pos];
let b = 0 != (current_byte & (128 >> self.used_bits)); let b = 0 != (current_byte & (128 >> self.used_bits));
self.increment_buffer_by_bit(); self.increment_buffer_by_bit();
Ok(b) Ok(b)
} }
pub fn u8(&mut self) -> Result<u8, String> { pub fn u8(&mut self) -> Result<u8, Error> {
self.bits8(8) self.bits8(8)
} }
pub fn bytes(&mut self) -> Result<Vec<u8>, String> { pub fn bytes(&mut self) -> Result<Vec<u8>, Error> {
self.filler()?; self.filler()?;
self.byte_array() self.byte_array()
} }
pub fn char(&mut self) -> Result<char, String> { pub fn char(&mut self) -> Result<char, Error> {
Ok(char::from_u32(self.word()? as u32).unwrap()) let character = self.word()? as u32;
char::from_u32(character).ok_or(Error::DecodeChar(character))
} }
pub fn string(&mut self) -> Result<String, String> { pub fn string(&mut self) -> Result<String, Error> {
let mut s = String::new(); let mut s = String::new();
while self.bit()? { while self.bit()? {
s += &self.char()?.to_string(); s += &self.char()?.to_string();
@ -51,17 +56,17 @@ impl<'b> Decoder<'b> {
Ok(s) Ok(s)
} }
pub fn utf8(&mut self) -> Result<String, String> { pub fn utf8(&mut self) -> Result<String, Error> {
// TODO: Better Error Handling // TODO: Better Error Handling
Ok(String::from_utf8(Vec::<u8>::decode(self)?).unwrap()) String::from_utf8(Vec::<u8>::decode(self)?).map_err(Error::from)
} }
pub fn filler(&mut self) -> Result<(), String> { pub fn filler(&mut self) -> Result<(), Error> {
while self.zero()? {} while self.zero()? {}
Ok(()) Ok(())
} }
pub fn word(&mut self) -> Result<usize, String> { pub fn word(&mut self) -> Result<usize, Error> {
let mut leading_bit = 1; let mut leading_bit = 1;
let mut final_word: usize = 0; let mut final_word: usize = 0;
let mut shl: usize = 0; let mut shl: usize = 0;
@ -78,8 +83,8 @@ impl<'b> Decoder<'b> {
pub fn decode_list_with<T: Decode<'b>>( pub fn decode_list_with<T: Decode<'b>>(
&mut self, &mut self,
decoder_func: for<'r> fn(&'r mut Decoder) -> Result<T, String>, decoder_func: for<'r> fn(&'r mut Decoder) -> Result<T, Error>,
) -> Result<Vec<T>, String> { ) -> Result<Vec<T>, Error> {
let mut vec_array: Vec<T> = Vec::new(); let mut vec_array: Vec<T> = Vec::new();
while self.bit()? { while self.bit()? {
vec_array.push(decoder_func(self)?) vec_array.push(decoder_func(self)?)
@ -87,46 +92,60 @@ impl<'b> Decoder<'b> {
Ok(vec_array) Ok(vec_array)
} }
fn zero(&mut self) -> Result<bool, String> { fn zero(&mut self) -> Result<bool, Error> {
let current_bit = self.bit()?; let current_bit = self.bit()?;
Ok(!current_bit) Ok(!current_bit)
} }
fn bit(&mut self) -> Result<bool, String> { fn bit(&mut self) -> Result<bool, Error> {
if self.pos >= self.buffer.len() { if self.pos >= self.buffer.len() {
return Err("DecoderState: Reached end of buffer".to_string()); return Err(Error::EndOfBuffer);
} }
let b = self.buffer[self.pos] & (128 >> self.used_bits) > 0; let b = self.buffer[self.pos] & (128 >> self.used_bits) > 0;
self.increment_buffer_by_bit(); self.increment_buffer_by_bit();
Ok(b) Ok(b)
} }
fn byte_array(&mut self) -> Result<Vec<u8>, String> { fn byte_array(&mut self) -> Result<Vec<u8>, Error> {
if self.used_bits != 0 { if self.used_bits != 0 {
return Err("DecoderState.byteArray: Buffer is not byte aligned".to_string()); return Err(Error::BufferNotByteAligned);
} }
self.ensure_bytes(1)?; self.ensure_bytes(1)?;
let mut blk_len = self.buffer[self.pos]; let mut blk_len = self.buffer[self.pos];
self.pos += 1; self.pos += 1;
let mut blk_array: Vec<u8> = Vec::new(); let mut blk_array: Vec<u8> = Vec::new();
while blk_len != 0 { while blk_len != 0 {
self.ensure_bytes(blk_len as usize + 1)?; self.ensure_bytes(blk_len as usize + 1)?;
let decoded_array = &self.buffer[self.pos..self.pos + blk_len as usize]; let decoded_array = &self.buffer[self.pos..self.pos + blk_len as usize];
blk_array.extend(decoded_array); blk_array.extend(decoded_array);
self.pos += blk_len as usize; self.pos += blk_len as usize;
blk_len = self.buffer[self.pos]; blk_len = self.buffer[self.pos];
} }
Ok(blk_array) Ok(blk_array)
} }
// can decode up to a max of 8 bits // can decode up to a max of 8 bits
pub fn bits8(&mut self, num_bits: usize) -> Result<u8, String> { pub fn bits8(&mut self, num_bits: usize) -> Result<u8, Error> {
if num_bits > 8 { if num_bits > 8 {
return Err( return Err(Error::IncorrectNumBits);
"Decoder.bits8: incorrect value of num_bits - must be less than 9".to_string(),
);
} }
self.ensure_bits(num_bits)?; self.ensure_bits(num_bits)?;
let unused_bits = 8 - self.used_bits as usize; let unused_bits = 8 - self.used_bits as usize;
let leading_zeroes = 8 - num_bits; let leading_zeroes = 8 - num_bits;
let r = (self.buffer[self.pos] << self.used_bits as usize) >> leading_zeroes; let r = (self.buffer[self.pos] << self.used_bits as usize) >> leading_zeroes;
@ -136,31 +155,29 @@ impl<'b> Decoder<'b> {
} else { } else {
r r
}; };
self.drop_bits(num_bits); self.drop_bits(num_bits);
Ok(x) Ok(x)
} }
fn ensure_bytes(&mut self, required_bytes: usize) -> Result<(), String> { fn ensure_bytes(&mut self, required_bytes: usize) -> Result<(), Error> {
if required_bytes as isize > self.buffer.len() as isize - self.pos as isize { if required_bytes as isize > self.buffer.len() as isize - self.pos as isize {
return Err(format!( Err(Error::NotEnoughBytes(required_bytes))
"DecoderState: Not enough data available: {:#?} - required bytes {}", } else {
self.buffer, required_bytes
));
}
Ok(()) Ok(())
} }
}
fn ensure_bits(&mut self, required_bits: usize) -> Result<(), String> { fn ensure_bits(&mut self, required_bits: usize) -> Result<(), Error> {
if required_bits as isize if required_bits as isize
> (self.buffer.len() as isize - self.pos as isize) * 8 - self.used_bits as isize > (self.buffer.len() as isize - self.pos as isize) * 8 - self.used_bits as isize
{ {
return Err(format!( Err(Error::NotEnoughBits(required_bits))
"DecoderState: Not enough data available: {:#?} - required bits {}", } else {
self.buffer, required_bits
));
}
Ok(()) Ok(())
} }
}
fn drop_bits(&mut self, num_bits: usize) { fn drop_bits(&mut self, num_bits: usize) {
let all_used_bits = num_bits as i64 + self.used_bits; let all_used_bits = num_bits as i64 + self.used_bits;

View File

@ -0,0 +1,23 @@
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("Reached end of buffer")]
EndOfBuffer,
#[error("Buffer is not byte aligned")]
BufferNotByteAligned,
#[error("Incorrect value of num_bits, must be less than 9")]
IncorrectNumBits,
#[error("Not enough data available, required {0} bytes")]
NotEnoughBytes(usize),
#[error("Not enough data available, required {0} bits")]
NotEnoughBits(usize),
#[error(transparent)]
DecodeUtf8(#[from] std::string::FromUtf8Error),
#[error("Decoding u32 to char {0}")]
DecodeChar(u32),
#[error("{0}")]
Message(String),
#[error(transparent)]
Custom(#[from] anyhow::Error),
}

View File

@ -1,11 +1,17 @@
use crate::{encoder::Encoder, filler::Filler}; mod encoder;
mod error;
use crate::filler::Filler;
pub use encoder::Encoder;
pub use error::Error;
pub trait Encode { pub trait Encode {
fn encode(&self, e: &mut Encoder) -> Result<(), String>; fn encode(&self, e: &mut Encoder) -> Result<(), Error>;
} }
impl Encode for bool { impl Encode for bool {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.bool(*self); e.bool(*self);
Ok(()) Ok(())
@ -13,7 +19,7 @@ impl Encode for bool {
} }
impl Encode for u8 { impl Encode for u8 {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.u8(*self)?; e.u8(*self)?;
Ok(()) Ok(())
@ -21,15 +27,15 @@ impl Encode for u8 {
} }
impl Encode for isize { impl Encode for isize {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.integer(*self)?; e.integer(*self);
Ok(()) Ok(())
} }
} }
impl Encode for usize { impl Encode for usize {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.word(*self); e.word(*self);
Ok(()) Ok(())
@ -37,15 +43,15 @@ impl Encode for usize {
} }
impl Encode for char { impl Encode for char {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.char(*self)?; e.char(*self);
Ok(()) Ok(())
} }
} }
impl Encode for &str { impl Encode for &str {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.utf8(self)?; e.utf8(self)?;
Ok(()) Ok(())
@ -53,7 +59,7 @@ impl Encode for &str {
} }
impl Encode for String { impl Encode for String {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.utf8(self)?; e.utf8(self)?;
Ok(()) Ok(())
@ -61,7 +67,7 @@ impl Encode for String {
} }
impl Encode for Vec<u8> { impl Encode for Vec<u8> {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.bytes(self)?; e.bytes(self)?;
Ok(()) Ok(())
@ -69,7 +75,7 @@ impl Encode for Vec<u8> {
} }
impl Encode for &[u8] { impl Encode for &[u8] {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.bytes(self)?; e.bytes(self)?;
Ok(()) Ok(())
@ -77,7 +83,7 @@ impl Encode for &[u8] {
} }
impl<T: Encode> Encode for Box<T> { impl<T: Encode> Encode for Box<T> {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
self.as_ref().encode(e)?; self.as_ref().encode(e)?;
Ok(()) Ok(())
@ -85,7 +91,7 @@ impl<T: Encode> Encode for Box<T> {
} }
impl Encode for Filler { impl Encode for Filler {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), Error> {
e.filler(); e.filler();
Ok(()) Ok(())

View File

@ -1,5 +1,7 @@
use crate::{encode::Encode, zigzag}; use crate::{encode::Encode, zigzag};
use super::Error;
pub struct Encoder { pub struct Encoder {
pub buffer: Vec<u8>, pub buffer: Vec<u8>,
// Int // Int
@ -24,12 +26,13 @@ impl Encoder {
} }
/// Encode any type that implements [`Encode`]. /// Encode any type that implements [`Encode`].
pub fn encode<T: Encode>(&mut self, x: T) -> Result<&mut Self, String> { pub fn encode<T: Encode>(&mut self, x: T) -> Result<&mut Self, Error> {
x.encode(self)?; x.encode(self)?;
Ok(self) Ok(self)
} }
pub fn u8(&mut self, x: u8) -> Result<&mut Self, String> { pub fn u8(&mut self, x: u8) -> Result<&mut Self, Error> {
if self.used_bits == 0 { if self.used_bits == 0 {
self.current_byte = x; self.current_byte = x;
self.next_word(); self.next_word();
@ -51,93 +54,54 @@ impl Encoder {
self self
} }
pub fn bytes(&mut self, x: &[u8]) -> Result<&mut Self, String> { pub fn bytes(&mut self, x: &[u8]) -> Result<&mut Self, Error> {
// use filler to write current buffer so bits used gets reset // use filler to write current buffer so bits used gets reset
self.filler(); self.filler();
self.byte_array(x) self.byte_array(x)
} }
pub fn byte_array(&mut self, arr: &[u8]) -> Result<&mut Self, String> { pub fn byte_array(&mut self, arr: &[u8]) -> Result<&mut Self, Error> {
if self.used_bits != 0 { if self.used_bits != 0 {
return Err("Buffer is not byte aligned".to_string()); return Err(Error::BufferNotByteAligned);
} }
self.write_blk(arr, &mut 0); self.write_blk(arr, &mut 0);
Ok(self) Ok(self)
} }
pub fn integer(&mut self, i: isize) -> Result<&mut Self, String> { pub fn integer(&mut self, i: isize) -> &mut Self {
let i = zigzag::to_usize(i); let i = zigzag::to_usize(i);
self.word(i); self.word(i);
Ok(self)
self
} }
pub fn char(&mut self, c: char) -> Result<&mut Self, String> { pub fn char(&mut self, c: char) -> &mut Self {
self.word(c as usize); self.word(c as usize);
Ok(self)
self
} }
// TODO: Do we need this? // TODO: Do we need this?
pub fn string(&mut self, s: &str) -> Result<&mut Self, String> { pub fn string(&mut self, s: &str) -> &mut Self {
for i in s.chars() { for i in s.chars() {
self.one(); self.one();
self.char(i)?; self.char(i);
} }
self.zero(); self.zero();
Ok(self) self
} }
pub fn utf8(&mut self, s: &str) -> Result<&mut Self, String> { pub fn utf8(&mut self, s: &str) -> Result<&mut Self, Error> {
self.bytes(s.as_bytes()) self.bytes(s.as_bytes())
} }
fn zero(&mut self) { pub fn word(&mut self, c: usize) -> &mut Self {
if self.used_bits == 7 {
self.next_word();
} else {
self.used_bits += 1;
}
}
fn one(&mut self) {
if self.used_bits == 7 {
self.current_byte |= 1;
self.next_word();
} else {
self.current_byte |= 128 >> self.used_bits;
self.used_bits += 1;
}
}
fn byte_unaligned(&mut self, x: u8) {
let x_shift = self.current_byte | (x >> self.used_bits);
self.buffer.push(x_shift);
self.current_byte = x << (8 - self.used_bits);
}
fn next_word(&mut self) {
self.buffer.push(self.current_byte);
self.current_byte = 0;
self.used_bits = 0;
}
fn write_blk(&mut self, arr: &[u8], src_ptr: &mut usize) {
let src_len = arr.len() - *src_ptr;
let blk_len = src_len.min(255);
self.buffer.push(blk_len as u8);
if blk_len == 0 {
return;
}
self.buffer.extend(&arr[*src_ptr..blk_len]);
*src_ptr += blk_len;
self.write_blk(arr, src_ptr);
}
pub fn word(&mut self, c: usize) {
loop { loop {
let mut w = (c & 127) as u8; let mut w = (c & 127) as u8;
let c = c >> 7; let c = c >> 7;
@ -151,22 +115,26 @@ impl Encoder {
break; break;
} }
} }
self
} }
pub fn encode_list_with( pub fn encode_list_with(
&mut self, &mut self,
encoder_func: for<'r> fn(u8, &'r mut Encoder) -> Result<(), String>,
list: Vec<u8>, list: Vec<u8>,
) -> Result<(), String> { encoder_func: for<'r> fn(u8, &'r mut Encoder) -> Result<(), Error>,
) -> Result<&mut Self, Error> {
for item in list { for item in list {
self.one(); self.one();
encoder_func(item, self)?; encoder_func(item, self)?;
} }
self.zero(); self.zero();
Ok(())
Ok(self)
} }
pub fn bits(&mut self, num_bits: i64, val: u8) { pub fn bits(&mut self, num_bits: i64, val: u8) -> &mut Self {
match (num_bits, val) { match (num_bits, val) {
(1, 0) => self.zero(), (1, 0) => self.zero(),
(1, 1) => self.one(), (1, 1) => self.one(),
@ -207,10 +175,63 @@ impl Encoder {
} }
} }
} }
self
} }
pub(crate) fn filler(&mut self) { pub(crate) fn filler(&mut self) -> &mut Self {
self.current_byte |= 1; self.current_byte |= 1;
self.next_word(); self.next_word();
self
}
fn zero(&mut self) {
if self.used_bits == 7 {
self.next_word();
} else {
self.used_bits += 1;
}
}
fn one(&mut self) {
if self.used_bits == 7 {
self.current_byte |= 1;
self.next_word();
} else {
self.current_byte |= 128 >> self.used_bits;
self.used_bits += 1;
}
}
fn byte_unaligned(&mut self, x: u8) {
let x_shift = self.current_byte | (x >> self.used_bits);
self.buffer.push(x_shift);
self.current_byte = x << (8 - self.used_bits);
}
fn next_word(&mut self) {
self.buffer.push(self.current_byte);
self.current_byte = 0;
self.used_bits = 0;
}
fn write_blk(&mut self, arr: &[u8], src_ptr: &mut usize) {
let src_len = arr.len() - *src_ptr;
let blk_len = src_len.min(255);
self.buffer.push(blk_len as u8);
if blk_len == 0 {
return;
}
self.buffer.extend(&arr[*src_ptr..blk_len]);
*src_ptr += blk_len;
self.write_blk(arr, src_ptr);
} }
} }

View File

@ -0,0 +1,11 @@
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("Buffer is not byte aligned")]
BufferNotByteAligned,
#[error("{0}")]
Message(String),
#[error(transparent)]
Custom(#[from] anyhow::Error),
}

View File

@ -1,13 +1,13 @@
pub enum Filler { pub enum Filler {
// FillerStart(Box<Filler>), FillerStart(Box<Filler>),
FillerEnd, FillerEnd,
} }
// impl Filler { impl Filler {
// pub fn len(&self) -> usize { pub fn length(&self) -> usize {
// match self { match self {
// Filler::FillerStart(f) => f.len() + 1, Filler::FillerStart(f) => f.length() + 1,
// Filler::FillerEnd => 1, Filler::FillerEnd => 1,
// } }
// } }
// } }

View File

@ -1,31 +1,27 @@
mod decode; mod decode;
mod decoder;
mod encode; mod encode;
mod encoder; pub mod filler;
mod filler;
pub mod zigzag; pub mod zigzag;
pub mod en { pub mod en {
pub use super::encode::*; pub use super::encode::*;
pub use super::encoder::*;
} }
pub mod de { pub mod de {
pub use super::decode::*; pub use super::decode::*;
pub use super::decoder::*;
} }
pub trait Flat<'b>: en::Encode + de::Decode<'b> { pub trait Flat<'b>: en::Encode + de::Decode<'b> {
fn flat(&self) -> Result<Vec<u8>, String> { fn flat(&self) -> Result<Vec<u8>, en::Error> {
encode(self) encode(self)
} }
fn unflat(bytes: &'b [u8]) -> Result<Self, String> { fn unflat(bytes: &'b [u8]) -> Result<Self, de::Error> {
decode(bytes) decode(bytes)
} }
} }
pub fn encode<T>(value: &T) -> Result<Vec<u8>, String> pub fn encode<T>(value: &T) -> Result<Vec<u8>, en::Error>
where where
T: en::Encode, T: en::Encode,
{ {
@ -37,7 +33,7 @@ where
Ok(e.buffer) Ok(e.buffer)
} }
pub fn decode<'b, T>(bytes: &'b [u8]) -> Result<T, String> pub fn decode<'b, T>(bytes: &'b [u8]) -> Result<T, de::Error>
where where
T: de::Decode<'b>, T: de::Decode<'b>,
{ {

View File

@ -6,7 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
anyhow = "1.0.57"
combine = "4.6.4" combine = "4.6.4"
flat = { path = "../flat" } flat = { path = "../flat" }
hex = "0.4.3" hex = "0.4.3"

View File

@ -1,3 +1,4 @@
use flat::de;
use strum_macros::EnumString; use strum_macros::EnumString;
#[repr(u8)] #[repr(u8)]
@ -80,6 +81,8 @@ pub enum DefaultFunction {
} }
impl TryFrom<u8> for DefaultFunction { impl TryFrom<u8> for DefaultFunction {
type Error = de::Error;
fn try_from(v: u8) -> Result<Self, Self::Error> { fn try_from(v: u8) -> Result<Self, Self::Error> {
match v { match v {
v if v == DefaultFunction::AddInteger as u8 => Ok(DefaultFunction::AddInteger), v if v == DefaultFunction::AddInteger as u8 => Ok(DefaultFunction::AddInteger),
@ -184,9 +187,7 @@ impl TryFrom<u8> for DefaultFunction {
v if v == DefaultFunction::MkPairData as u8 => Ok(DefaultFunction::MkPairData), v if v == DefaultFunction::MkPairData as u8 => Ok(DefaultFunction::MkPairData),
v if v == DefaultFunction::MkNilData as u8 => Ok(DefaultFunction::MkNilData), v if v == DefaultFunction::MkNilData as u8 => Ok(DefaultFunction::MkNilData),
v if v == DefaultFunction::MkNilPairData as u8 => Ok(DefaultFunction::MkNilPairData), v if v == DefaultFunction::MkNilPairData as u8 => Ok(DefaultFunction::MkNilPairData),
_ => Err("Default Function not found".to_string()), _ => Err(de::Error::Message("Default Function not found".to_string())),
} }
} }
type Error = String;
} }

View File

@ -9,7 +9,7 @@ struct Level(usize);
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum Error { pub enum Error {
#[error("Free Unique: `{0}`")] #[error("Free Unique `{0}`")]
FreeUnique(Unique), FreeUnique(Unique),
} }

View File

@ -1,8 +1,6 @@
use anyhow::anyhow;
use flat::{ use flat::{
de::{Decode, Decoder}, de::{self, Decode, Decoder},
en::{Encode, Encoder}, en::{self, Encode, Encoder},
Flat, Flat,
}; };
@ -16,8 +14,8 @@ const CONST_TAG_WIDTH: u32 = 4;
const TERM_TAG_WIDTH: u32 = 4; const TERM_TAG_WIDTH: u32 = 4;
pub trait Binder<'b>: Encode + Decode<'b> { pub trait Binder<'b>: Encode + Decode<'b> {
fn binder_encode(&self, e: &mut Encoder) -> Result<(), String>; fn binder_encode(&self, e: &mut Encoder) -> Result<(), en::Error>;
fn binder_decode(d: &mut Decoder) -> Result<Self, String>; fn binder_decode(d: &mut Decoder) -> Result<Self, de::Error>;
} }
impl<'b, T> Flat<'b> for Program<T> where T: Binder<'b> {} impl<'b, T> Flat<'b> for Program<T> where T: Binder<'b> {}
@ -28,12 +26,12 @@ where
{ {
// convenient so that people don't need to depend on the flat crate // convenient so that people don't need to depend on the flat crate
// directly to call programs flat function // directly to call programs flat function
pub fn to_flat(&self) -> anyhow::Result<Vec<u8>> { pub fn to_flat(&self) -> Result<Vec<u8>, en::Error> {
self.flat().map_err(|err| anyhow!("{}", err)) self.flat()
} }
pub fn flat_hex(&self) -> anyhow::Result<String> { pub fn flat_hex(&self) -> Result<String, en::Error> {
let bytes = self.flat().map_err(|err| anyhow!("{}", err))?; let bytes = self.flat()?;
let hex = hex::encode(&bytes); let hex = hex::encode(&bytes);
@ -45,7 +43,7 @@ impl<'b, T> Encode for Program<T>
where where
T: Binder<'b>, T: Binder<'b>,
{ {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
let (major, minor, patch) = self.version; let (major, minor, patch) = self.version;
major.encode(e)?; major.encode(e)?;
@ -62,7 +60,7 @@ impl<'b, T> Decode<'b> for Program<T>
where where
T: Binder<'b>, T: Binder<'b>,
{ {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
let version = (usize::decode(d)?, usize::decode(d)?, usize::decode(d)?); let version = (usize::decode(d)?, usize::decode(d)?, usize::decode(d)?);
let term = Term::decode(d)?; let term = Term::decode(d)?;
Ok(Program { version, term }) Ok(Program { version, term })
@ -73,7 +71,7 @@ impl<'b, T> Encode for Term<T>
where where
T: Binder<'b>, T: Binder<'b>,
{ {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
match self { match self {
Term::Var(name) => { Term::Var(name) => {
encode_term_tag(0, e)?; encode_term_tag(0, e)?;
@ -125,7 +123,7 @@ impl<'b, T> Decode<'b> for Term<T>
where where
T: Binder<'b>, T: Binder<'b>,
{ {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
match decode_term_tag(d)? { match decode_term_tag(d)? {
0 => Ok(Term::Var(T::decode(d)?)), 0 => Ok(Term::Var(T::decode(d)?)),
1 => Ok(Term::Delay(Box::new(Term::decode(d)?))), 1 => Ok(Term::Delay(Box::new(Term::decode(d)?))),
@ -142,13 +140,16 @@ where
5 => Ok(Term::Force(Box::new(Term::decode(d)?))), 5 => Ok(Term::Force(Box::new(Term::decode(d)?))),
6 => Ok(Term::Error), 6 => Ok(Term::Error),
7 => Ok(Term::Builtin(DefaultFunction::decode(d)?)), 7 => Ok(Term::Builtin(DefaultFunction::decode(d)?)),
x => Err(format!("Unknown term constructor tag: {}", x)), x => Err(de::Error::Message(format!(
"Unknown term constructor tag: {}",
x
))),
} }
} }
} }
impl Encode for &Constant { impl Encode for &Constant {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
match self { match self {
Constant::Integer(i) => { Constant::Integer(i) => {
encode_constant(0, e)?; encode_constant(0, e)?;
@ -182,20 +183,23 @@ impl Encode for &Constant {
} }
impl<'b> Decode<'b> for Constant { impl<'b> Decode<'b> for Constant {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
match decode_constant(d)? { match decode_constant(d)? {
0 => Ok(Constant::Integer(isize::decode(d)?)), 0 => Ok(Constant::Integer(isize::decode(d)?)),
1 => Ok(Constant::ByteString(Vec::<u8>::decode(d)?)), 1 => Ok(Constant::ByteString(Vec::<u8>::decode(d)?)),
2 => Ok(Constant::String(String::decode(d)?)), 2 => Ok(Constant::String(String::decode(d)?)),
3 => Ok(Constant::Unit), 3 => Ok(Constant::Unit),
4 => Ok(Constant::Bool(bool::decode(d)?)), 4 => Ok(Constant::Bool(bool::decode(d)?)),
x => Err(format!("Unknown constant constructor tag: {}", x)), x => Err(de::Error::Message(format!(
"Unknown constant constructor tag: {}",
x
))),
} }
} }
} }
impl Encode for Unique { impl Encode for Unique {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
isize::from(*self).encode(e)?; isize::from(*self).encode(e)?;
Ok(()) Ok(())
@ -203,13 +207,13 @@ impl Encode for Unique {
} }
impl<'b> Decode<'b> for Unique { impl<'b> Decode<'b> for Unique {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
Ok(isize::decode(d)?.into()) Ok(isize::decode(d)?.into())
} }
} }
impl Encode for Name { impl Encode for Name {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
self.text.encode(e)?; self.text.encode(e)?;
self.unique.encode(e)?; self.unique.encode(e)?;
@ -218,7 +222,7 @@ impl Encode for Name {
} }
impl<'b> Decode<'b> for Name { impl<'b> Decode<'b> for Name {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
Ok(Name { Ok(Name {
text: String::decode(d)?, text: String::decode(d)?,
unique: Unique::decode(d)?, unique: Unique::decode(d)?,
@ -227,19 +231,19 @@ impl<'b> Decode<'b> for Name {
} }
impl<'b> Binder<'b> for Name { impl<'b> Binder<'b> for Name {
fn binder_encode(&self, e: &mut Encoder) -> Result<(), String> { fn binder_encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
self.encode(e)?; self.encode(e)?;
Ok(()) Ok(())
} }
fn binder_decode(d: &mut Decoder) -> Result<Self, String> { fn binder_decode(d: &mut Decoder) -> Result<Self, de::Error> {
Name::decode(d) Name::decode(d)
} }
} }
impl Encode for NamedDeBruijn { impl Encode for NamedDeBruijn {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
self.text.encode(e)?; self.text.encode(e)?;
self.index.encode(e)?; self.index.encode(e)?;
@ -248,7 +252,7 @@ impl Encode for NamedDeBruijn {
} }
impl<'b> Decode<'b> for NamedDeBruijn { impl<'b> Decode<'b> for NamedDeBruijn {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
Ok(NamedDeBruijn { Ok(NamedDeBruijn {
text: String::decode(d)?, text: String::decode(d)?,
index: DeBruijn::decode(d)?, index: DeBruijn::decode(d)?,
@ -257,13 +261,13 @@ impl<'b> Decode<'b> for NamedDeBruijn {
} }
impl<'b> Binder<'b> for NamedDeBruijn { impl<'b> Binder<'b> for NamedDeBruijn {
fn binder_encode(&self, e: &mut Encoder) -> Result<(), String> { fn binder_encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
self.text.encode(e)?; self.text.encode(e)?;
Ok(()) Ok(())
} }
fn binder_decode(d: &mut Decoder) -> Result<Self, String> { fn binder_decode(d: &mut Decoder) -> Result<Self, de::Error> {
Ok(NamedDeBruijn { Ok(NamedDeBruijn {
text: String::decode(d)?, text: String::decode(d)?,
index: DeBruijn::new(0), index: DeBruijn::new(0),
@ -272,7 +276,7 @@ impl<'b> Binder<'b> for NamedDeBruijn {
} }
impl Encode for DeBruijn { impl Encode for DeBruijn {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
usize::from(*self).encode(e)?; usize::from(*self).encode(e)?;
Ok(()) Ok(())
@ -280,23 +284,23 @@ impl Encode for DeBruijn {
} }
impl<'b> Decode<'b> for DeBruijn { impl<'b> Decode<'b> for DeBruijn {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
Ok(usize::decode(d)?.into()) Ok(usize::decode(d)?.into())
} }
} }
impl<'b> Binder<'b> for DeBruijn { impl<'b> Binder<'b> for DeBruijn {
fn binder_encode(&self, _: &mut Encoder) -> Result<(), String> { fn binder_encode(&self, _: &mut Encoder) -> Result<(), en::Error> {
Ok(()) Ok(())
} }
fn binder_decode(_d: &mut Decoder) -> Result<Self, String> { fn binder_decode(_d: &mut Decoder) -> Result<Self, de::Error> {
Ok(DeBruijn::new(0)) Ok(DeBruijn::new(0))
} }
} }
impl Encode for DefaultFunction { impl Encode for DefaultFunction {
fn encode(&self, e: &mut Encoder) -> Result<(), String> { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
e.bits(BUILTIN_TAG_WIDTH as i64, self.clone() as u8); e.bits(BUILTIN_TAG_WIDTH as i64, self.clone() as u8);
Ok(()) Ok(())
@ -304,53 +308,55 @@ impl Encode for DefaultFunction {
} }
impl<'b> Decode<'b> for DefaultFunction { impl<'b> Decode<'b> for DefaultFunction {
fn decode(d: &mut Decoder) -> Result<Self, String> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
let builtin_tag = d.bits8(BUILTIN_TAG_WIDTH as usize)?; let builtin_tag = d.bits8(BUILTIN_TAG_WIDTH as usize)?;
builtin_tag.try_into() builtin_tag.try_into()
} }
} }
fn encode_term_tag(tag: u8, e: &mut Encoder) -> Result<(), String> { fn encode_term_tag(tag: u8, e: &mut Encoder) -> Result<(), en::Error> {
safe_encode_bits(TERM_TAG_WIDTH, tag, e) safe_encode_bits(TERM_TAG_WIDTH, tag, e)
} }
fn decode_term_tag(d: &mut Decoder) -> Result<u8, String> { fn decode_term_tag(d: &mut Decoder) -> Result<u8, de::Error> {
d.bits8(TERM_TAG_WIDTH as usize) d.bits8(TERM_TAG_WIDTH as usize)
} }
fn safe_encode_bits(num_bits: u32, byte: u8, e: &mut Encoder) -> Result<(), String> { fn safe_encode_bits(num_bits: u32, byte: u8, e: &mut Encoder) -> Result<(), en::Error> {
if 2_u8.pow(num_bits) < byte { if 2_u8.pow(num_bits) < byte {
Err(format!( Err(en::Error::Message(format!(
"Overflow detected, cannot fit {} in {} bits.", "Overflow detected, cannot fit {} in {} bits.",
byte, num_bits byte, num_bits
)) )))
} else { } else {
e.bits(num_bits as i64, byte); e.bits(num_bits as i64, byte);
Ok(()) Ok(())
} }
} }
pub fn encode_constant(tag: u8, e: &mut Encoder) -> Result<(), String> { pub fn encode_constant(tag: u8, e: &mut Encoder) -> Result<(), en::Error> {
e.encode_list_with(encode_constant_tag, [tag].to_vec()) e.encode_list_with([tag].to_vec(), encode_constant_tag)?;
Ok(())
} }
pub fn decode_constant(d: &mut Decoder) -> Result<u8, String> { pub fn decode_constant(d: &mut Decoder) -> Result<u8, de::Error> {
let u8_list = d.decode_list_with(decode_constant_tag)?; let u8_list = d.decode_list_with(decode_constant_tag)?;
if u8_list.len() > 1 { if u8_list.len() > 1 {
Err( Err(de::Error::Message(
"Improper encoding on constant tag. Should be list of one item encoded in 4 bits" "Improper encoding on constant tag. Should be list of one item encoded in 4 bits"
.to_string(), .to_string(),
) ))
} else { } else {
Ok(u8_list[0]) Ok(u8_list[0])
} }
} }
pub fn encode_constant_tag(tag: u8, e: &mut Encoder) -> Result<(), String> { pub fn encode_constant_tag(tag: u8, e: &mut Encoder) -> Result<(), en::Error> {
safe_encode_bits(CONST_TAG_WIDTH, tag, e) safe_encode_bits(CONST_TAG_WIDTH, tag, e)
} }
pub fn decode_constant_tag(d: &mut Decoder) -> Result<u8, String> { pub fn decode_constant_tag(d: &mut Decoder) -> Result<u8, de::Error> {
d.bits8(CONST_TAG_WIDTH as usize) d.bits8(CONST_TAG_WIDTH as usize)
} }

View File

@ -1,7 +1,9 @@
use std::{collections::HashMap, str::FromStr}; use std::{collections::HashMap, str::FromStr};
use combine::{ use combine::{
attempt, between, choice, many1, attempt, between, choice,
error::StringStreamError,
many1,
parser::{ parser::{
char::{alpha_num, digit, hex_digit, space, spaces, string}, char::{alpha_num, digit, hex_digit, space, spaces, string},
combinator::no_partial, combinator::no_partial,
@ -46,18 +48,15 @@ impl ParserState {
} }
} }
pub fn program(src: &str) -> anyhow::Result<Program<Name>> { pub fn program(src: &str) -> Result<Program<Name>, StringStreamError> {
let mut parser = program_(); let mut parser = program_();
let result = parser.parse(state::Stream { let (program, _) = parser.parse(state::Stream {
stream: position::Stream::new(src.trim()), stream: position::Stream::new(src.trim()),
state: ParserState::new(), state: ParserState::new(),
}); })?;
match result { Ok(program)
Ok((program, _)) => Ok(program),
Err(err) => Err(anyhow::anyhow!("{}", err)),
}
} }
fn program_<Input>() -> impl Parser<StateStream<Input>, Output = Program<Name>> fn program_<Input>() -> impl Parser<StateStream<Input>, Output = Program<Name>>