cde 0.3.7

A universal encoding scheme for all cryptographic data
Documentation
use crate::{CryptoData, Error, ENCODER};
use core::{
    convert::{From, Into},
    fmt,
    ops::{Deref, DerefMut},
};

#[derive(Clone, Copy, Default, PartialEq)]
pub struct VarUInt(u64);

impl<'a> From<&'a [u8]> for VarUInt {
    fn from(buf: &'a [u8]) -> VarUInt {
        let mut v = 0u64;
        for (i, b) in buf.iter().cloned().enumerate() {
            let k = u64::from(b & 0x7f);
            v |= k << (i * 7);
            if b & 0x80 == 0 {
                break;
            }
        }
        VarUInt(v)
    }
}

impl VarUInt {
    pub fn try_parse(buf: &[u8]) -> Result<Self, Error> {
        let mut complete = false;
        let mut v = 0u64;
        for (i, b) in buf.iter().cloned().enumerate() {
            let k = u64::from(b & 0x7f);
            v |= k << (i * 7);
            if b & 0x80 == 0 {
                complete = true;
                break;
            }
        }

        if complete {
            return Ok(VarUInt(v));
        } else {
            return Err(Error::InvalidLength);
        }
    }
}

impl From<u64> for VarUInt {
    fn from(v: u64) -> VarUInt {
        VarUInt(v)
    }
}

impl Into<u64> for VarUInt {
    fn into(self) -> u64 {
        self.0
    }
}

impl From<usize> for VarUInt {
    fn from(v: usize) -> VarUInt {
        VarUInt(v as u64)
    }
}

impl Into<usize> for VarUInt {
    fn into(self) -> usize {
        self.0 as usize
    }
}

impl fmt::Display for VarUInt {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl Deref for VarUInt {
    type Target = u64;

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

impl DerefMut for VarUInt {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl CryptoData for VarUInt {
    fn len(&self) -> usize {
        match self.0 {
            n if n < 128 => 1,
            n if n >= 128 && n < 268_435_456 => 4,
            n if n >= 268_435_456 && n < 562_949_953_421_311 => 7,
            _ => 7,
        }
    }

    fn bytes(&self, buf: &mut [u8]) -> usize {
        let mut v = self.0;
        for b in buf.iter_mut() {
            *b = v as u8 | 0x80;
            v >>= 7;
            if v == 0 {
                *b &= 0x7f;
                break;
            }
        }
        self.len()
    }

    fn encode_len(&self) -> usize {
        ENCODER.encode_len(self.len())
    }

    fn encode(&self, buf: &mut [u8]) -> usize {
        let mut b = [0u8; 7];
        self.bytes(&mut b);
        ENCODER.encode_mut(&b[0..self.len()], buf);
        self.encode_len()
    }
}