use hex::FromHexError;
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Hash)]
pub enum BinaryError {
InvalidCharacters,
AlreadyHasWhitespace,
InvalidByteSize,
UnknownError,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Hash, Default)]
pub struct BinaryString(pub String);
#[deprecated]
pub struct BinaryUsage;
impl From<&str> for BinaryString {
fn from(n: &str) -> Self {
let bytes = n.as_bytes();
let mut bin_string: String = String::new();
for byte in bytes {
bin_string.push_str(&format!("{:08b}", byte));
}
return BinaryString(bin_string);
}
}
impl From<String> for BinaryString {
fn from(n: String) -> Self {
let bytes: Vec<u8> = n.into_bytes();
let mut bin_string: String = String::new();
for byte in bytes {
bin_string.push_str(&format!("{:08b}", byte));
}
return BinaryString(bin_string);
}
}
impl From<&[u8]> for BinaryString {
fn from(byte_slice: &[u8]) -> Self {
let bytes: Vec<u8> = byte_slice.to_vec();
let mut bin_string: String = String::new();
for byte in bytes {
bin_string.push_str(&format!("{:08b}", byte));
}
return BinaryString(bin_string);
}
}
impl From<[u8; 32]> for BinaryString {
fn from(array: [u8; 32]) -> Self {
let mut bin_string: String = String::new();
for byte in &array {
bin_string.push_str(&format!("{:08b}", byte));
}
return BinaryString(bin_string);
}
}
impl From<Vec<u8>> for BinaryString {
fn from(bytes: Vec<u8>) -> BinaryString {
let mut bin_string: String = String::new();
for byte in bytes {
bin_string.push_str(&format!("{:08b}", byte));
}
return BinaryString(bin_string);
}
}
impl From<u8> for BinaryString {
fn from(byte: u8) -> BinaryString {
let mut bin_string: String = String::new();
bin_string.push_str(&format!("{:08b}", byte));
return BinaryString(bin_string);
}
}
impl BinaryString {
pub fn from_hex<T: AsRef<[u8]>>(n: T) -> Result<BinaryString, FromHexError> {
let bytes: Vec<u8> = hex::decode(n).unwrap();
let mut bin_string: String = String::new();
for byte in bytes {
bin_string.push_str(&format!("{:08b}", byte));
}
return Ok(BinaryString(bin_string));
}
}
impl fmt::Display for BinaryString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl BinaryString {
pub fn assert_binary(&self) -> bool {
for x in self.0.chars() {
if x == '0' || x == '1' {
} else {
return false;
}
}
return true;
}
pub fn assert_binary_string(&self) -> bool {
for x in self.0.chars() {
if x == '0' || x == '1' {
} else {
return false;
}
}
return true;
}
pub fn assert_binary_whitespace(&self) -> bool {
for x in self.0.chars() {
if x == '0' || x == '1' || x == ' ' {
} else {
return false;
}
}
return true;
}
pub fn assert_bytes(&self) -> bool {
if self.bits().unwrap() % 8usize == 0usize {
return true;
} else {
return false;
}
}
pub fn assert_bit_length(&self, len: usize) -> bool {
if self.bits().unwrap() == len {
return true;
} else {
return false;
}
}
pub fn assert_byte_length(&self, len: usize) -> bool {
if self.bytes().unwrap() == len {
return true;
} else {
return false;
}
}
pub fn bits(&self) -> Result<usize, BinaryError> {
if self.assert_binary_string() == true {
return Ok(self.0.len());
} else if self.assert_binary_whitespace() == true {
let no_spaces = self.remove_spaces();
return Ok(no_spaces.0.len());
} else {
return Err(BinaryError::InvalidCharacters);
}
}
pub fn bytes(&self) -> Result<usize, BinaryError> {
if self.assert_bytes() == true {
return Ok(self.bits().unwrap() / 8usize);
} else if self.assert_bytes() == false {
return Err(BinaryError::InvalidByteSize);
} else {
Err(BinaryError::UnknownError)
}
}
pub fn remove_spaces(&self) -> BinaryString {
BinaryString(self.0.chars().filter(|c| !c.is_whitespace()).collect())
}
pub fn add_spaces(&self) -> Result<BinaryString, BinaryError> {
if self.assert_binary_string() == true && self.assert_bytes() {
let mut binary_string_with_spaces = self.0.clone();
let bytes_to_index: usize = self.bytes().unwrap() - 1usize;
let mut counter: usize = 8;
for _ in 0..bytes_to_index {
binary_string_with_spaces.insert(counter, ' ');
counter = counter + 9usize;
}
return Ok(BinaryString(binary_string_with_spaces));
} else if self.assert_binary_whitespace() == true {
return Err(BinaryError::AlreadyHasWhitespace);
} else {
Err(BinaryError::InvalidCharacters)
}
}
}
#[allow(deprecated)]
impl BinaryUsage {
pub fn assert_binary(bin: String) -> bool {
for x in bin.chars() {
if x == '0' || x == '1' {
} else {
return false;
}
}
return true;
}
pub fn assert_binary_string(bin: String) -> bool {
for x in bin.chars() {
if x == '0' || x == '1' {
} else {
return false;
}
}
return true;
}
pub fn assert_binary_whitespace(bin: String) -> bool {
for x in bin.chars() {
if x == '0' || x == '1' || x == ' ' {
} else {
return false;
}
}
return true;
}
pub fn assert_bytes(bin: String) -> bool {
if BinaryUsage::count_bits(bin).unwrap() % 8usize == 0usize {
return true;
} else {
return false;
}
}
pub fn count_bits(bin: String) -> Result<usize, ()> {
if BinaryUsage::assert_binary_string(bin.clone()) == true {
return Ok(bin.len());
} else if BinaryUsage::assert_binary_whitespace(bin.clone()) == true {
return Ok(BinaryUsage::remove_spaces(bin).len());
} else {
return Err(());
}
}
pub fn count_bytes(bin: String) -> Result<usize, ()> {
if BinaryUsage::assert_bytes(bin.clone()) == true {
return Ok(BinaryUsage::count_bits(bin).unwrap() / 8usize);
} else {
Err(())
}
}
pub fn add_spaces(bin: String) -> Result<String, ()> {
if BinaryUsage::assert_binary_string(bin.clone()) == true
&& BinaryUsage::assert_bytes(bin.clone())
{
let mut binary_string_with_spaces = bin.clone();
let bytes_to_index: usize = BinaryUsage::count_bytes(bin).unwrap() - 1usize;
let mut counter: usize = 8;
for _ in 0..bytes_to_index {
binary_string_with_spaces.insert(counter, ' ');
counter = counter + 9usize;
}
return Ok(binary_string_with_spaces);
} else if BinaryUsage::assert_binary_whitespace(bin.clone()) == true {
return Ok(bin);
} else {
Err(())
}
}
pub fn remove_spaces(bin: String) -> String {
bin.chars().filter(|c| !c.is_whitespace()).collect()
}
}