2024-06-08 21:51:30 +00:00
|
|
|
#[derive(Default, Clone, Copy, Debug)]
|
|
|
|
pub enum VarFormat {
|
|
|
|
ASCII,
|
|
|
|
Binary,
|
|
|
|
BinaryWithGroups,
|
2024-06-08 23:38:44 +00:00
|
|
|
// #[default]
|
2024-06-08 21:51:30 +00:00
|
|
|
Hexadecimal,
|
|
|
|
Octal,
|
2024-06-08 23:38:44 +00:00
|
|
|
#[default]
|
2024-06-08 21:51:30 +00:00
|
|
|
Signed,
|
|
|
|
Unsigned,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VarFormat {
|
|
|
|
pub fn as_static_str(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
VarFormat::ASCII => "Text",
|
|
|
|
VarFormat::Binary => "Bin",
|
|
|
|
VarFormat::BinaryWithGroups => "Bins",
|
|
|
|
VarFormat::Hexadecimal => "Hex",
|
|
|
|
VarFormat::Octal => "Oct",
|
2024-06-08 23:38:44 +00:00
|
|
|
VarFormat::Signed => "Int",
|
|
|
|
VarFormat::Unsigned => "UInt",
|
2024-06-08 21:51:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn next(&self) -> Self {
|
|
|
|
match self {
|
|
|
|
VarFormat::ASCII => VarFormat::Binary,
|
|
|
|
VarFormat::Binary => VarFormat::BinaryWithGroups,
|
|
|
|
VarFormat::BinaryWithGroups => VarFormat::Hexadecimal,
|
|
|
|
VarFormat::Hexadecimal => VarFormat::Octal,
|
|
|
|
VarFormat::Octal => VarFormat::Signed,
|
|
|
|
VarFormat::Signed => VarFormat::Unsigned,
|
|
|
|
VarFormat::Unsigned => VarFormat::ASCII,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn format(&self, value: wellen::SignalValue) -> String {
|
|
|
|
// @TODO optimize it by not using `.to_string` if possible
|
|
|
|
let value = value.to_string();
|
2024-06-08 23:38:44 +00:00
|
|
|
if value.is_empty() {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
match self {
|
|
|
|
VarFormat::ASCII => {
|
|
|
|
// @TODO
|
|
|
|
value
|
|
|
|
},
|
|
|
|
VarFormat::Binary => {
|
|
|
|
value
|
|
|
|
},
|
|
|
|
VarFormat::BinaryWithGroups => {
|
|
|
|
// @TODO
|
|
|
|
value
|
|
|
|
},
|
|
|
|
VarFormat::Hexadecimal => {
|
|
|
|
let ones_and_zeros = value
|
|
|
|
.chars()
|
|
|
|
.rev()
|
|
|
|
.map(|char| char.to_digit(2).unwrap())
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
let mut base = convert_base::Convert::new(2, 16);
|
|
|
|
let output = base.convert::<u32, u32>(&ones_and_zeros);
|
|
|
|
let value: String = output
|
|
|
|
.into_iter()
|
|
|
|
.rev()
|
|
|
|
.map(|number| char::from_digit(number, 16).unwrap())
|
|
|
|
.collect();
|
|
|
|
value
|
|
|
|
},
|
|
|
|
VarFormat::Octal => {
|
|
|
|
let ones_and_zeros = value
|
|
|
|
.chars()
|
|
|
|
.rev()
|
|
|
|
.map(|char| char.to_digit(2).unwrap())
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
let mut base = convert_base::Convert::new(2, 8);
|
|
|
|
let output = base.convert::<u32, u32>(&ones_and_zeros);
|
|
|
|
let value: String = output
|
|
|
|
.into_iter()
|
|
|
|
.rev()
|
|
|
|
.map(|number| char::from_digit(number, 8).unwrap())
|
|
|
|
.collect();
|
|
|
|
value
|
|
|
|
},
|
|
|
|
VarFormat::Signed => {
|
|
|
|
let mut ones_and_zeros = value
|
|
|
|
.chars()
|
|
|
|
.rev()
|
|
|
|
.map(|char| char.to_digit(2).unwrap())
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
// https://builtin.com/articles/twos-complement
|
|
|
|
let sign = if ones_and_zeros.last().unwrap() == &0 { "" } else { "-" };
|
|
|
|
if sign == "-" {
|
|
|
|
let mut one_found = false;
|
|
|
|
for one_or_zero in &mut ones_and_zeros {
|
|
|
|
if one_found {
|
|
|
|
*one_or_zero = if one_or_zero == &0 {
|
|
|
|
1
|
|
|
|
} else {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
} else if one_or_zero == &1 {
|
|
|
|
one_found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut base = convert_base::Convert::new(2, 10);
|
|
|
|
let output = base.convert::<u32, u32>(&ones_and_zeros);
|
|
|
|
let value_without_sign: String = output
|
|
|
|
.into_iter()
|
|
|
|
.rev()
|
|
|
|
.map(|number| char::from_digit(number, 10).unwrap())
|
|
|
|
.collect();
|
|
|
|
// @TODO chain `sign` before collecting?
|
|
|
|
let value = sign.to_owned() + &value_without_sign;
|
|
|
|
value
|
|
|
|
},
|
|
|
|
VarFormat::Unsigned => {
|
|
|
|
let ones_and_zeros = value
|
|
|
|
.chars()
|
|
|
|
.rev()
|
|
|
|
.map(|char| char.to_digit(2).unwrap())
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
let mut base = convert_base::Convert::new(2, 10);
|
|
|
|
let output = base.convert::<u32, u32>(&ones_and_zeros);
|
|
|
|
let value: String = output
|
|
|
|
.into_iter()
|
|
|
|
.rev()
|
|
|
|
.map(|number| char::from_digit(number, 10).unwrap())
|
|
|
|
.collect();
|
|
|
|
value
|
|
|
|
},
|
|
|
|
}
|
2024-06-08 21:51:30 +00:00
|
|
|
}
|
|
|
|
}
|