use borsh::{BorshDeserialize, BorshSerialize};
use byteorder::{LittleEndian, ReadBytesExt};
use near_primitives_core::hash::{hash, CryptoHash};
use std::io::{Cursor, Read};
#[derive(BorshSerialize, BorshDeserialize, Clone, PartialEq, Eq, Debug)]
pub struct ValueRef {
pub length: u32,
pub hash: CryptoHash,
}
impl ValueRef {
pub fn new(value: &[u8]) -> Self {
Self { length: value.len() as u32, hash: hash(value) }
}
pub fn decode(bytes: &[u8]) -> Result<Self, std::io::Error> {
let mut cursor = Cursor::new(bytes);
let value_length = cursor.read_u32::<LittleEndian>()?;
let mut arr = [0; 32];
cursor.read_exact(&mut arr)?;
let value_hash = CryptoHash(arr);
Ok(ValueRef { length: value_length, hash: value_hash })
}
}
#[cfg(test)]
mod tests {
use crate::state::ValueRef;
use near_primitives_core::hash::hash;
#[test]
fn test_encode_decode() {
let value = vec![1, 2, 3];
let old_value_ref = ValueRef::new(&value);
let mut value_ref_ser = [0u8; 36];
value_ref_ser[0..4].copy_from_slice(&old_value_ref.length.to_le_bytes());
value_ref_ser[4..36].copy_from_slice(&old_value_ref.hash.0);
let value_ref = ValueRef::decode(&value_ref_ser).unwrap();
assert_eq!(value_ref.length, value.len() as u32);
assert_eq!(value_ref.hash, hash(&value));
}
}