feat: prepare decoding traits and make new Flat trait
This commit is contained in:
parent
41487733f7
commit
0a476d0592
|
@ -11,7 +11,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
println!("{:#?}", program);
|
println!("{:#?}", program);
|
||||||
|
|
||||||
let flat_bytes = program.flat()?;
|
let flat_bytes = program.to_flat()?;
|
||||||
|
|
||||||
for byte in flat_bytes {
|
for byte in flat_bytes {
|
||||||
print!("{:08b} ", byte);
|
print!("{:08b} ", byte);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
use crate::decoder::Decoder;
|
||||||
|
|
||||||
|
pub trait Decode<'b>: Sized {
|
||||||
|
fn decode(d: &mut Decoder<'b>) -> Result<Self, String>;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
use crate::decode::Decode;
|
||||||
|
|
||||||
|
pub struct Decoder<'b> {
|
||||||
|
buffer: &'b [u8],
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> Decoder<'b> {
|
||||||
|
pub fn new(bytes: &'b [u8]) -> Decoder<'b> {
|
||||||
|
Decoder {
|
||||||
|
buffer: bytes,
|
||||||
|
pos: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode<T: Decode<'b>>(&mut self) -> Result<T, String> {
|
||||||
|
T::decode(self)
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,19 +83,6 @@ impl<T: Encode> Encode for Box<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, K> Encode for (T, K)
|
|
||||||
where
|
|
||||||
T: Encode,
|
|
||||||
K: Encode,
|
|
||||||
{
|
|
||||||
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
|
||||||
self.0.encode(e)?;
|
|
||||||
self.1.encode(e)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encode for Filler {
|
impl Encode for Filler {
|
||||||
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
e.filler();
|
e.filler();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
mod decode;
|
||||||
|
mod decoder;
|
||||||
mod encode;
|
mod encode;
|
||||||
mod encoder;
|
mod encoder;
|
||||||
mod filler;
|
mod filler;
|
||||||
|
@ -8,33 +10,58 @@ pub mod en {
|
||||||
pub use super::encoder::*;
|
pub use super::encoder::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode<T>(value: T) -> Result<Vec<u8>, String>
|
pub mod de {
|
||||||
|
pub use super::decode::*;
|
||||||
|
pub use super::decoder::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Flat<'b>: en::Encode + de::Decode<'b> {
|
||||||
|
fn flat(&self) -> Result<Vec<u8>, String> {
|
||||||
|
encode(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unflat(bytes: &'b [u8]) -> Result<Self, String> {
|
||||||
|
decode(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode<T>(value: &T) -> Result<Vec<u8>, String>
|
||||||
where
|
where
|
||||||
T: en::Encode,
|
T: en::Encode,
|
||||||
{
|
{
|
||||||
let mut e = en::Encoder::new();
|
let mut e = en::Encoder::new();
|
||||||
|
|
||||||
e.encode((value, filler::Filler::FillerEnd))?;
|
value.encode(&mut e)?;
|
||||||
|
e.encode(filler::Filler::FillerEnd)?;
|
||||||
|
|
||||||
Ok(e.buffer)
|
Ok(e.buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn decode<'b, T>(bytes: &'b [u8]) -> Result<T, String>
|
||||||
|
where
|
||||||
|
T: de::Decode<'b>,
|
||||||
|
{
|
||||||
|
let mut d = de::Decoder::new(bytes);
|
||||||
|
|
||||||
|
d.decode()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn encode_bool() {
|
fn encode_bool() {
|
||||||
let bytes = super::encode(true).unwrap();
|
let bytes = super::encode(&true).unwrap();
|
||||||
|
|
||||||
assert_eq!(bytes, vec![0b10000001]);
|
assert_eq!(bytes, vec![0b10000001]);
|
||||||
|
|
||||||
let bytes = super::encode(false).unwrap();
|
let bytes = super::encode(&false).unwrap();
|
||||||
|
|
||||||
assert_eq!(bytes, vec![0b00000001]);
|
assert_eq!(bytes, vec![0b00000001]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn encode_u8() {
|
fn encode_u8() {
|
||||||
let bytes = super::encode(3_u8).unwrap();
|
let bytes = super::encode(&3_u8).unwrap();
|
||||||
|
|
||||||
assert_eq!(bytes, vec![0b00000011, 0b00000001]);
|
assert_eq!(bytes, vec![0b00000011, 0b00000001]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
|
||||||
use flat::en::{Encode, Encoder};
|
use flat::{
|
||||||
|
de::{Decode, Decoder},
|
||||||
|
en::{Encode, Encoder},
|
||||||
|
Flat,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Constant, Program, Term},
|
ast::{Constant, Program, Term},
|
||||||
|
@ -11,15 +15,17 @@ const BUILTIN_TAG_WIDTH: u32 = 7;
|
||||||
const CONST_TAG_WIDTH: u32 = 4;
|
const CONST_TAG_WIDTH: u32 = 4;
|
||||||
const TERM_TAG_WIDTH: u32 = 4;
|
const TERM_TAG_WIDTH: u32 = 4;
|
||||||
|
|
||||||
impl Program {
|
impl<'b> Flat<'b> for Program {}
|
||||||
pub fn flat(&self) -> anyhow::Result<Vec<u8>> {
|
|
||||||
let bytes = flat::encode(self.clone()).map_err(|err| anyhow!("{}", err))?;
|
|
||||||
|
|
||||||
Ok(bytes)
|
impl Program {
|
||||||
|
// 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 flat_hex(&self) -> anyhow::Result<String> {
|
pub fn flat_hex(&self) -> anyhow::Result<String> {
|
||||||
let bytes = self.flat()?;
|
let bytes = self.flat().map_err(|err| anyhow!("{}", err))?;
|
||||||
|
|
||||||
let hex = hex::encode(&bytes);
|
let hex = hex::encode(&bytes);
|
||||||
|
|
||||||
|
@ -41,6 +47,12 @@ impl Encode for Program {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'b> Decode<'b> for Program {
|
||||||
|
fn decode(_d: &mut Decoder<'b>) -> Result<Self, String> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Encode for Term {
|
impl Encode for Term {
|
||||||
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
// still need annotation but here we have the term tags
|
// still need annotation but here we have the term tags
|
||||||
|
@ -92,6 +104,12 @@ impl Encode for Term {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'b> Decode<'b> for Term {
|
||||||
|
fn decode(_d: &mut Decoder<'b>) -> Result<Self, String> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Encode for &Constant {
|
impl Encode for &Constant {
|
||||||
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -128,6 +146,12 @@ impl Encode for &Constant {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'b> Decode<'b> for Constant {
|
||||||
|
fn decode(_d: &mut Decoder<'b>) -> Result<Self, String> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Encode for DefaultFunction {
|
impl Encode for DefaultFunction {
|
||||||
fn encode(&self, e: &mut flat::en::Encoder) -> Result<(), String> {
|
fn encode(&self, e: &mut flat::en::Encoder) -> Result<(), String> {
|
||||||
e.bits(BUILTIN_TAG_WIDTH as i64, self.clone() as u8);
|
e.bits(BUILTIN_TAG_WIDTH as i64, self.clone() as u8);
|
||||||
|
@ -136,6 +160,12 @@ impl Encode for DefaultFunction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'b> Decode<'b> for DefaultFunction {
|
||||||
|
fn decode(_d: &mut Decoder<'b>) -> Result<Self, String> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn encode_term_tag(tag: u8, e: &mut Encoder) -> Result<(), String> {
|
fn encode_term_tag(tag: u8, e: &mut Encoder) -> Result<(), String> {
|
||||||
safe_encode_bits(TERM_TAG_WIDTH, tag, e)
|
safe_encode_bits(TERM_TAG_WIDTH, tag, e)
|
||||||
}
|
}
|
||||||
|
@ -171,7 +201,7 @@ mod test {
|
||||||
term: Term::Constant(Constant::Integer(11)),
|
term: Term::Constant(Constant::Integer(11)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let bytes = program.flat().unwrap();
|
let bytes = program.to_flat().unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bytes,
|
bytes,
|
||||||
|
|
Loading…
Reference in New Issue