feat: clean up errors

This commit is contained in:
rvcas
2022-06-04 14:01:45 -04:00
parent 377c5c206c
commit 1ecd47a361
15 changed files with 294 additions and 204 deletions

View File

@@ -1,3 +1,4 @@
use flat::de;
use strum_macros::EnumString;
#[repr(u8)]
@@ -80,6 +81,8 @@ pub enum DefaultFunction {
}
impl TryFrom<u8> for DefaultFunction {
type Error = de::Error;
fn try_from(v: u8) -> Result<Self, Self::Error> {
match v {
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::MkNilData as u8 => Ok(DefaultFunction::MkNilData),
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)]
pub enum Error {
#[error("Free Unique: `{0}`")]
#[error("Free Unique `{0}`")]
FreeUnique(Unique),
}

View File

@@ -1,8 +1,6 @@
use anyhow::anyhow;
use flat::{
de::{Decode, Decoder},
en::{Encode, Encoder},
de::{self, Decode, Decoder},
en::{self, Encode, Encoder},
Flat,
};
@@ -16,8 +14,8 @@ const CONST_TAG_WIDTH: u32 = 4;
const TERM_TAG_WIDTH: u32 = 4;
pub trait Binder<'b>: Encode + Decode<'b> {
fn binder_encode(&self, e: &mut Encoder) -> Result<(), String>;
fn binder_decode(d: &mut Decoder) -> Result<Self, String>;
fn binder_encode(&self, e: &mut Encoder) -> Result<(), en::Error>;
fn binder_decode(d: &mut Decoder) -> Result<Self, de::Error>;
}
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
// directly to call programs flat function
pub fn to_flat(&self) -> anyhow::Result<Vec<u8>> {
self.flat().map_err(|err| anyhow!("{}", err))
pub fn to_flat(&self) -> Result<Vec<u8>, en::Error> {
self.flat()
}
pub fn flat_hex(&self) -> anyhow::Result<String> {
let bytes = self.flat().map_err(|err| anyhow!("{}", err))?;
pub fn flat_hex(&self) -> Result<String, en::Error> {
let bytes = self.flat()?;
let hex = hex::encode(&bytes);
@@ -45,7 +43,7 @@ impl<'b, T> Encode for Program<T>
where
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;
major.encode(e)?;
@@ -62,7 +60,7 @@ impl<'b, T> Decode<'b> for Program<T>
where
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 term = Term::decode(d)?;
Ok(Program { version, term })
@@ -73,7 +71,7 @@ impl<'b, T> Encode for Term<T>
where
T: Binder<'b>,
{
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
match self {
Term::Var(name) => {
encode_term_tag(0, e)?;
@@ -125,7 +123,7 @@ impl<'b, T> Decode<'b> for Term<T>
where
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)? {
0 => Ok(Term::Var(T::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)?))),
6 => Ok(Term::Error),
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 {
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
match self {
Constant::Integer(i) => {
encode_constant(0, e)?;
@@ -182,20 +183,23 @@ impl Encode 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)? {
0 => Ok(Constant::Integer(isize::decode(d)?)),
1 => Ok(Constant::ByteString(Vec::<u8>::decode(d)?)),
2 => Ok(Constant::String(String::decode(d)?)),
3 => Ok(Constant::Unit),
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 {
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> {
isize::from(*self).encode(e)?;
Ok(())
@@ -203,13 +207,13 @@ impl Encode 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())
}
}
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.unique.encode(e)?;
@@ -218,7 +222,7 @@ impl Encode 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 {
text: String::decode(d)?,
unique: Unique::decode(d)?,
@@ -227,19 +231,19 @@ impl<'b> Decode<'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)?;
Ok(())
}
fn binder_decode(d: &mut Decoder) -> Result<Self, String> {
fn binder_decode(d: &mut Decoder) -> Result<Self, de::Error> {
Name::decode(d)
}
}
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.index.encode(e)?;
@@ -248,7 +252,7 @@ impl Encode 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 {
text: String::decode(d)?,
index: DeBruijn::decode(d)?,
@@ -257,13 +261,13 @@ impl<'b> Decode<'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)?;
Ok(())
}
fn binder_decode(d: &mut Decoder) -> Result<Self, String> {
fn binder_decode(d: &mut Decoder) -> Result<Self, de::Error> {
Ok(NamedDeBruijn {
text: String::decode(d)?,
index: DeBruijn::new(0),
@@ -272,7 +276,7 @@ impl<'b> Binder<'b> for NamedDeBruijn {
}
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)?;
Ok(())
@@ -280,23 +284,23 @@ impl Encode 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())
}
}
impl<'b> Binder<'b> for DeBruijn {
fn binder_encode(&self, _: &mut Encoder) -> Result<(), String> {
fn binder_encode(&self, _: &mut Encoder) -> Result<(), en::Error> {
Ok(())
}
fn binder_decode(_d: &mut Decoder) -> Result<Self, String> {
fn binder_decode(_d: &mut Decoder) -> Result<Self, de::Error> {
Ok(DeBruijn::new(0))
}
}
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);
Ok(())
@@ -304,53 +308,55 @@ impl Encode 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)?;
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)
}
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)
}
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 {
Err(format!(
Err(en::Error::Message(format!(
"Overflow detected, cannot fit {} in {} bits.",
byte, num_bits
))
)))
} else {
e.bits(num_bits as i64, byte);
Ok(())
}
}
pub fn encode_constant(tag: u8, e: &mut Encoder) -> Result<(), String> {
e.encode_list_with(encode_constant_tag, [tag].to_vec())
pub fn encode_constant(tag: u8, e: &mut Encoder) -> Result<(), en::Error> {
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)?;
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"
.to_string(),
)
))
} else {
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)
}
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)
}

View File

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