stacks-rs 0.1.1

A rust toolkit to interact with the stacks blockchain.
Documentation
use crate::clarity::ClarityValue;
use crate::clarity::Error;
use crate::clarity::CLARITY_TYPE_BUFFER;
use crate::crypto::hex::bytes_to_hex;
use crate::crypto::Deserialize;
use crate::crypto::Serialize;

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct BufferCV(u8, Vec<u8>);

impl BufferCV {
    pub fn new(value: &[u8]) -> ClarityValue {
        ClarityValue::Buffer(BufferCV(CLARITY_TYPE_BUFFER, value.to_vec()))
    }
}

impl std::fmt::Display for BufferCV {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "0x{}", bytes_to_hex(&self.1))
    }
}

impl std::fmt::Debug for BufferCV {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "BufferCV({self})")
    }
}

impl Serialize for BufferCV {
    type Err = Error;

    fn serialize(&self) -> Result<Vec<u8>, Self::Err> {
        let mut buff = vec![CLARITY_TYPE_BUFFER];
        buff.extend_from_slice(&(u32::try_from(self.1.len())?).to_be_bytes());
        buff.extend_from_slice(&self.1);
        Ok(buff)
    }
}

impl Deserialize for BufferCV {
    type Output = ClarityValue;
    type Err = Error;

    fn deserialize(bytes: &[u8]) -> Result<Self::Output, Self::Err> {
        if bytes[0] != CLARITY_TYPE_BUFFER {
            return Err(Error::InvalidClarityTypeId(CLARITY_TYPE_BUFFER, bytes[0]));
        }

        let len = u32::from_be_bytes([bytes[1], bytes[2], bytes[3], bytes[4]]);
        let mut offset = 5;

        let mut buff = vec![];

        for _ in 0..len {
            buff.push(bytes[offset]);
            offset += 1;
        }

        Ok(BufferCV::new(&buff))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::crypto::hex::hex_to_bytes;

    #[test]
    fn test_buffer_cv() {
        let buffer = BufferCV::new(&[0xde, 0xad, 0xbe, 0xef]);
        let serialized = buffer.serialize().unwrap();

        let hex = bytes_to_hex(&serialized);
        assert_eq!(hex, "0200000004deadbeef");

        let deserialized = BufferCV::deserialize(&serialized).unwrap();
        assert_eq!(buffer, deserialized);
    }

    #[test]
    fn test_buffer_cv_string() {
        let buffer = BufferCV::new(&hex_to_bytes("00").unwrap());
        assert_eq!(buffer.to_string(), "0x00");

        let buffer_2 = BufferCV::new(&[127]);
        assert_eq!(buffer_2.to_string(), "0x7f");

        let buffer_3 = BufferCV::new("\n".as_bytes());
        assert_eq!(buffer_3.to_string(), "0x0a");
    }
}