Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/aeserialization/bindings/Id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { EncodedId } from "./EncodedId";
import type { Tag } from "./Tag";

export interface Id { tag: Tag, val: EncodedId, }
3 changes: 3 additions & 0 deletions crates/aeserialization/bindings/Tag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

export type Tag = "Account" | "Name" | "Commitment" | "Oracle" | "Contract" | "Channel";
16 changes: 9 additions & 7 deletions crates/aeserialization/src/api_encoder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::error::DecodingErr;
use crate::id;
use crate::Bytes;
use crate::bytes::Bytes;

/// Possible chain-object types.
#[derive(Debug, Copy, Clone, PartialEq)]
Expand Down Expand Up @@ -215,17 +215,18 @@ impl Encoding {
fn make_check(self, data: &[u8]) -> Bytes {
use sha256::digest;
let d = digest(digest(data));
d.as_bytes()[..4].to_vec()
Bytes::from(&d.as_bytes()[..4])
}

fn add_check(self, data: &[u8]) -> Bytes {
let c = self.make_check(data);
vec![data, &c].concat()
Bytes::from(&vec![data, &c].concat())
}

fn encode(self, data: &[u8]) -> String {
match self {
Encoding::Base58 => bs58::encode(data).into_string(),
Encoding::Base58 =>
bs58::encode(data).into_string(),
Encoding::Base64 => {
use base64::engine::general_purpose::STANDARD;
use base64::Engine;
Expand All @@ -241,11 +242,12 @@ impl Encoding {

fn decode(self, data: &str) -> Option<Bytes> {
match self {
Encoding::Base58 => bs58::decode(data).into_vec().ok(),
Encoding::Base58 =>
bs58::decode(data).into_vec().ok(),
Encoding::Base64 => {
use base64::Engine;
use base64::engine::general_purpose::STANDARD;
STANDARD.decode(data).ok()
STANDARD.decode(data).ok().map(Bytes::from)
}
}
}
Expand Down Expand Up @@ -298,7 +300,7 @@ fn decode_check(tp: KnownType, data: &str) -> Result<Bytes, DecodingErr> {
let c = &dec[body_size..body_size + 4];
assert_eq!(c, tp.encoding().make_check(body));

Ok(body.to_vec())
Ok(Bytes::from(body))
}

/// Decodes data as an id.
Expand Down
122 changes: 122 additions & 0 deletions crates/aeserialization/src/bytes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
use crate::{rlp, error::DecodingErr};

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Bytes {
data: Vec<u8>,
}

impl Bytes {
pub fn from(data: &[u8]) -> Self {
Bytes {
data: data.to_vec(),
}
}

pub fn new() -> Self {
Bytes { data: Vec::new() }
}

pub fn to_vec(self) -> Vec<u8> {
self.data
}

pub fn len(&self) -> usize {
self.data.len()
}

pub fn is_empty(&self) -> bool {
self.data.is_empty()
}

pub fn reverse(&mut self) {
self.data.reverse()
}

pub fn extend(&mut self, data: &[u8]) {
self.data.extend(data)
}

pub fn resize(&mut self, size: usize, fill: u8) {
self.data.resize(size, fill)
}
}

impl std::ops::Index<usize> for Bytes {
type Output = u8;
fn index(&self, idx: usize) -> &Self::Output {
&self.data[idx]
}
}

impl std::ops::Index<core::ops::Range<usize>> for Bytes {
type Output = [u8];
fn index(&self, idx: core::ops::Range<usize>) -> &Self::Output {
&self.data[idx]
}
}

impl std::ops::Deref for Bytes {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.data
}
}

impl FromIterator<u8> for Bytes {
#[inline]
fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
Bytes {
data: Vec::<u8>::from_iter(iter),
}
}
}

impl IntoIterator for Bytes {
type Item = u8;
type IntoIter = <Vec<u8> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}

impl rlp::ToRlpItem for Bytes {
fn to_rlp_item(&self) -> rlp::RlpItem {
rlp::RlpItem::ByteArray(self.clone())
}
}

impl rlp::FromRlpItem for Bytes {
fn from_rlp_item(rlp: &rlp::RlpItem) -> Result<Bytes, DecodingErr> {
let arr = rlp.byte_array()?;
Ok(arr)
}
}

mod erlang {
use super::*;
use rustler::*;

impl Encoder for Bytes {
fn encode<'b>(&self, env: Env<'b>) -> Term<'b> {
let mut bin = types::binary::NewBinary::new(env, self.data.len());
let data = bin.as_mut_slice();
data.copy_from_slice(&self.data);

Binary::from(bin).to_term(env)
}
}

impl<'a> Decoder<'a> for Bytes {
fn decode(term: Term<'a>) -> NifResult<Bytes> {
if !term.is_binary() {
Err(Error::BadArg)?;
}

let bin = Binary::from_term(term)?;
let data = bin.as_slice();
Ok(Bytes {
data: data.to_vec(),
})
}
}
}
Loading