Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OwnedBytes and SizedBytes to clvm-utils #499

Closed
wants to merge 2 commits into from
Closed
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
4 changes: 4 additions & 0 deletions crates/clvm-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@

mod curried_program;
mod curry_tree_hash;
mod owned_atom;
mod sized_atom;
mod tree_hash;

pub use curried_program::*;
pub use curry_tree_hash::*;
pub use owned_atom::*;
pub use sized_atom::*;
pub use tree_hash::*;
92 changes: 92 additions & 0 deletions crates/clvm-utils/src/owned_atom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use std::ops::Deref;

use clvm_traits::{ClvmDecoder, ClvmEncoder, FromClvm, FromClvmError, ToClvm, ToClvmError};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct OwnedAtom(Vec<u8>);

impl OwnedAtom {
pub fn new(data: Vec<u8>) -> Self {
Self(data)
}

pub fn into_inner(self) -> Vec<u8> {
self.0
}
}

impl AsRef<[u8]> for OwnedAtom {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

impl From<Vec<u8>> for OwnedAtom {
fn from(data: Vec<u8>) -> Self {
Self(data)
}
}

impl From<OwnedAtom> for Vec<u8> {
fn from(atom: OwnedAtom) -> Self {
atom.0
}
}

impl Deref for OwnedAtom {
type Target = [u8];

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<N> ToClvm<N> for OwnedAtom {
fn to_clvm(&self, encoder: &mut impl ClvmEncoder<Node = N>) -> Result<N, ToClvmError> {
encoder.encode_atom(self)
}
}

impl<N> FromClvm<N> for OwnedAtom {
fn from_clvm(decoder: &impl ClvmDecoder<Node = N>, node: N) -> Result<Self, FromClvmError> {
decoder
.decode_atom(&node)
.map(|atom| Self::new(atom.as_ref().to_vec()))
}
}

#[cfg(test)]
mod tests {
use super::*;

use clvmr::{
serde::{node_from_bytes, node_to_bytes},
Allocator,
};

#[test]
fn test_to_clvm() {
let a = &mut Allocator::new();

let ptr = OwnedAtom::new(Vec::new()).to_clvm(a).unwrap();
let bytes = node_to_bytes(a, ptr).unwrap();
assert_eq!(hex::encode(bytes), "80".to_owned());

let ptr = OwnedAtom::new(b"hello".to_vec()).to_clvm(a).unwrap();
let bytes = node_to_bytes(a, ptr).unwrap();
assert_eq!(hex::encode(bytes), "8568656c6c6f".to_owned());
}

#[test]
fn test_from_clvm() {
let a = &mut Allocator::new();

let ptr = node_from_bytes(a, &hex::decode("80").unwrap()).unwrap();
let value = OwnedAtom::from_clvm(a, ptr).unwrap();
assert_eq!(value, OwnedAtom::new(Vec::new()));

let ptr = node_from_bytes(a, &hex::decode("8568656c6c6f").unwrap()).unwrap();
let value = OwnedAtom::from_clvm(a, ptr).unwrap();
assert_eq!(value, OwnedAtom::new(b"hello".to_vec()));
}
}
98 changes: 98 additions & 0 deletions crates/clvm-utils/src/sized_atom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use std::ops::Deref;

use clvm_traits::{ClvmDecoder, ClvmEncoder, FromClvm, FromClvmError, ToClvm, ToClvmError};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SizedAtom<const LEN: usize>([u8; LEN]);

impl<const LEN: usize> SizedAtom<LEN> {
pub fn new(data: [u8; LEN]) -> Self {
Self(data)
}

pub fn as_bytes(self) -> [u8; LEN] {
self.0
}
}

impl<const LEN: usize> AsRef<[u8]> for SizedAtom<LEN> {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

impl<const LEN: usize> Deref for SizedAtom<LEN> {
type Target = [u8];

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<const LEN: usize> From<[u8; LEN]> for SizedAtom<LEN> {
fn from(data: [u8; LEN]) -> Self {
Self(data)
}
}

impl<const LEN: usize> From<SizedAtom<LEN>> for [u8; LEN] {
fn from(atom: SizedAtom<LEN>) -> Self {
atom.0
}
}

impl<N, const LEN: usize> ToClvm<N> for SizedAtom<LEN> {
fn to_clvm(&self, encoder: &mut impl ClvmEncoder<Node = N>) -> Result<N, ToClvmError> {
encoder.encode_atom(self)
}
}

impl<N, const LEN: usize> FromClvm<N> for SizedAtom<LEN> {
fn from_clvm(decoder: &impl ClvmDecoder<Node = N>, node: N) -> Result<Self, FromClvmError> {
let atom = decoder.decode_atom(&node)?;
let bytes = atom.as_ref();

Ok(Self::new(bytes.try_into().map_err(|_| {
FromClvmError::WrongAtomLength {
expected: LEN,
found: bytes.len(),
}
})?))
}
}

#[cfg(test)]
mod tests {
use super::*;

use clvmr::{
serde::{node_from_bytes, node_to_bytes},
Allocator,
};

#[test]
fn test_to_clvm() {
let a = &mut Allocator::new();

let ptr = SizedAtom::new([]).to_clvm(a).unwrap();
let bytes = node_to_bytes(a, ptr).unwrap();
assert_eq!(hex::encode(bytes), "80".to_owned());

let ptr = SizedAtom::new(*b"hello").to_clvm(a).unwrap();
let bytes = node_to_bytes(a, ptr).unwrap();
assert_eq!(hex::encode(bytes), "8568656c6c6f".to_owned());
}

#[test]
fn test_from_clvm() {
let a = &mut Allocator::new();

let ptr = node_from_bytes(a, &hex::decode("80").unwrap()).unwrap();
let value = SizedAtom::from_clvm(a, ptr).unwrap();
assert_eq!(value, SizedAtom::new([]));

let ptr = node_from_bytes(a, &hex::decode("8568656c6c6f").unwrap()).unwrap();
let value = SizedAtom::from_clvm(a, ptr).unwrap();
assert_eq!(value, SizedAtom::new(*b"hello"));
}
}
Loading