feat: clean up errors
This commit is contained in:
parent
377c5c206c
commit
1ecd47a361
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
@ -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),
|
||||||
|
}
|
|
@ -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(())
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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),
|
||||||
|
}
|
|
@ -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,
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
|
@ -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>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>>
|
||||||
|
|
Loading…
Reference in New Issue