use crate::bfrt::Convert;
use crate::error::RBFRTError;
use std::array::TryFromSliceError;
use std::net::{Ipv4Addr, Ipv6Addr};
pub trait ToBytes {
fn to_bytes(&self) -> Vec<u8>;
fn to_u32(&self) -> u32 {
unimplemented!("Conversion not implemented.");
}
fn to_u64(&self) -> u64 {
unimplemented!("Conversion not implemented.");
}
fn to_u128(&self) -> u128 {
unimplemented!("Conversion not implemented.");
}
fn to_string(&self) -> String {
unimplemented!("Conversion not implemented.");
}
fn to_bool(&self) -> bool {
unimplemented!("Conversion not implemented.");
}
fn to_ipv4(&self) -> Result<Ipv4Addr, RBFRTError> {
unimplemented!("Conversion not implemented.");
}
fn to_ipv6(&self) -> Result<Ipv6Addr, RBFRTError> {
unimplemented!("Conversion not implemented.");
}
fn to_int_arr(&self) -> Vec<u32> {
unimplemented!("Conversion not implemented");
}
}
impl ToBytes for u8 {
fn to_bytes(&self) -> Vec<u8> {
u8::to_be_bytes(*self).to_vec()
}
}
impl ToBytes for i8 {
fn to_bytes(&self) -> Vec<u8> {
i8::to_be_bytes(*self).to_vec()
}
}
impl ToBytes for u16 {
fn to_bytes(&self) -> Vec<u8> {
u16::to_be_bytes(*self).to_vec()
}
}
impl ToBytes for i16 {
fn to_bytes(&self) -> Vec<u8> {
i16::to_be_bytes(*self).to_vec()
}
}
impl ToBytes for u32 {
fn to_bytes(&self) -> Vec<u8> {
u32::to_be_bytes(*self).to_vec()
}
}
impl ToBytes for u64 {
fn to_bytes(&self) -> Vec<u8> {
u64::to_be_bytes(*self).to_vec()
}
}
impl ToBytes for u128 {
fn to_bytes(&self) -> Vec<u8> {
u128::to_be_bytes(*self).to_vec()
}
}
impl ToBytes for i32 {
fn to_bytes(&self) -> Vec<u8> {
i32::to_be_bytes(*self).to_vec()
}
}
impl ToBytes for bool {
fn to_bytes(&self) -> Vec<u8> {
if *self {
vec![1]
} else {
vec![0]
}
}
}
impl ToBytes for Vec<u8> {
fn to_bytes(&self) -> Vec<u8> {
self.to_vec()
}
fn to_u32(&self) -> u32 {
let data = self.clone().convert("to_u32 call", 32).unwrap();
u32::from_be_bytes(data.try_into().unwrap())
}
fn to_u64(&self) -> u64 {
let data = self.clone().convert("to_u64 call", 64).unwrap();
u64::from_be_bytes(data.try_into().unwrap())
}
fn to_u128(&self) -> u128 {
let data = self.clone().convert("to_u128 call", 128).unwrap();
u128::from_be_bytes(data.try_into().unwrap())
}
fn to_string(&self) -> String {
std::str::from_utf8(self).unwrap().to_string()
}
fn to_bool(&self) -> bool {
self.iter().any(|&x| x > 0u8)
}
fn to_ipv4(&self) -> Result<Ipv4Addr, RBFRTError> {
let octets: [u8; 4] = self[..].try_into().map_err(|e: TryFromSliceError| {
RBFRTError::ByteConversionError {
target: "Ipv4Addr".to_owned(),
orig_e: e.into(),
}
})?;
Ok(Ipv4Addr::from(octets))
}
fn to_int_arr(&self) -> Vec<u32> {
let mut ret = vec![];
for (i, v) in self.iter().enumerate().step_by(4) {
ret.push(unsafe {
u32::from_be_bytes([
*v,
*self.get_unchecked(i + 1),
*self.get_unchecked(i + 2),
*self.get_unchecked(i + 3),
])
});
}
ret
}
fn to_ipv6(&self) -> Result<Ipv6Addr, RBFRTError> {
let octets: [u8; 16] = self[..].try_into().map_err(|e: TryFromSliceError| {
RBFRTError::ByteConversionError {
target: "Ipv6Addr".to_owned(),
orig_e: e.into(),
}
})?;
Ok(Ipv6Addr::from(octets))
}
}
impl ToBytes for String {
fn to_bytes(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}
impl ToBytes for &str {
fn to_bytes(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}
impl ToBytes for Ipv4Addr {
fn to_bytes(&self) -> Vec<u8> {
self.octets().to_vec()
}
}
impl ToBytes for Ipv6Addr {
fn to_bytes(&self) -> Vec<u8> {
self.octets().to_vec()
}
}
impl ToBytes for Vec<u32> {
fn to_bytes(&self) -> Vec<u8> {
self.iter().flat_map(|val| val.to_be_bytes()).collect()
}
}