rlibbencode 0.1.0

Rust Bencode library
Documentation
use std::any::Any;
use std::{fmt, io};
use std::fmt::Formatter;
use crate::variables::inter::bencode_types::BencodeTypes;
use crate::variables::inter::bencode_variable::{BencodeCast, BencodeVariable, FromBencode, ToBencode};

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

impl BencodeVariable for BencodeNumber {

    fn get_type(&self) -> BencodeTypes {
        BencodeTypes::Number
    }

    fn upcast(self) -> Box<dyn BencodeVariable> {
        Box::new(self)
    }

    fn as_any(&self) -> &dyn Any {
        self
    }

    fn as_any_mut(&mut self) -> &mut dyn Any {
        self
    }

    fn clone_box(&self) -> Box<dyn BencodeVariable> {
        Box::new(self.clone())
    }
}

macro_rules! impl_bencode_number {
    ($($type:ty)*) => {
        $(
            impl From<$type> for BencodeNumber {

                fn from(value: $type) -> Self {
                    Self {
                        value: value.to_string().as_bytes().to_vec()
                    }
                }
            }

            impl BencodeCast<BencodeNumber> for $type {

                fn cast(value: &BencodeNumber) -> io::Result<Self> {
                    Ok(String::from_utf8(value.value.clone()).unwrap().parse::<$type>().unwrap())
                }
            }

            impl From<$type> for Box<dyn BencodeVariable> {

                fn from(value: $type) -> Self {
                    Box::new(BencodeNumber {
                        value: value.to_string().as_bytes().to_vec()
                    })
                }
            }
        )*
    }
}

impl_bencode_number!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64);

impl ToBencode for BencodeNumber {

    fn to_bencode(&self) -> Vec<u8> {
        let mut buf = Vec::new();
        buf.push(BencodeTypes::Number.prefix());
        buf.extend_from_slice(&self.value);
        buf.push(BencodeTypes::Number.suffix());
        buf
    }
}

impl FromBencode for BencodeNumber {

    fn from_bencode_with_offset(buf: &[u8]) -> io::Result<(Self, usize)> {
        if !BencodeTypes::from_code(buf[0]).eq(&BencodeTypes::Number) {
            return Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid prefix for number"));
        }

        let mut off = 1;
        while buf[off] != BencodeTypes::Number.suffix() {
            off += 1;
        }

        Ok((Self {
            value: buf[1..off].to_vec()
        }, off + 1))
    }
}

impl fmt::Display for BencodeNumber {

    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{}", String::from_utf8(self.value.clone()).unwrap())
    }
}