Skip to content

Commit

Permalink
Barebone string conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
Coloquinte committed Jan 8, 2024
1 parent 4d80a1b commit f4b3784
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 17 deletions.
35 changes: 35 additions & 0 deletions src/lut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,27 @@ impl Lut {
}
table_complexity(num_vars, table.as_slice())
}

/// Return the hexadecimal string representing the function
///
/// Contrary to display, nothing else in printed: `a45b` instead of `Lut4(a45b)`
pub fn to_hex_string(&self) -> String {
to_hex(self.num_vars(), self.table.as_ref())
}

/// Return the binary string representing the function
///
/// Contrary to display, nothing else in printed: `0101` instead of `Lut2(0101)`
pub fn to_bin_string(&self) -> String {
to_bin(self.num_vars(), self.table.as_ref())
}

/// Build a Lut from an hexadecimal string
pub fn from_hex_string(num_vars: usize, s: &str) -> Result<Self, ()> {

Check warning on line 383 in src/lut.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

this returns a `Result<_, ()>`

warning: this returns a `Result<_, ()>` --> src/lut.rs:383:5 | 383 | pub fn from_hex_string(num_vars: usize, s: &str) -> Result<Self, ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a custom `Error` type instead = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#result_unit_err = note: `#[warn(clippy::result_unit_err)]` on by default
let mut ret = Lut::zero(num_vars);
fill_hex(ret.num_vars(), ret.table.as_mut(), s)?;
Ok(ret)
}
}

#[doc(hidden)]
Expand Down Expand Up @@ -1099,4 +1120,18 @@ mod tests {
}
}
}

#[test]
#[cfg(feature = "rand")]
fn test_string_conversion() {
for num_vars in 0..8 {
for _ in 0..10 {
let lut = Lut::random(num_vars);
assert_eq!(
lut,
Lut::from_hex_string(num_vars, &lut.to_hex_string()).unwrap()
);
}
}
}
}
74 changes: 57 additions & 17 deletions src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,25 +230,45 @@ pub fn cmp(table1: &[u64], table2: &[u64]) -> std::cmp::Ordering {
return table1.iter().rev().cmp(table2.iter().rev());
}

/// Hexadecimal formatting
pub fn fmt_hex(
num_vars: usize,
table: &[u64],
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
/// Expected size of the string for one chunk
fn hex_str_size(num_vars: usize) -> usize {
let i = num_vars;
write!(f, "Lut{:}(", i)?;
let width = if i >= 6 {
if i >= 6 {
16
} else if i <= 2 {
1
} else {
1 << (i - 2)
};
}
}

/// Hexadecimal string representation of the function
pub fn to_hex(num_vars: usize, table: &[u64]) -> String {
let width = hex_str_size(num_vars);
let mut s = String::new();
for t in table.iter().rev() {
s.push_str(&format!("{:0width$x}", t));
}
s
}

/// Hexadecimal formatting
pub fn fmt_hex(
num_vars: usize,
table: &[u64],
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
write!(f, "Lut{:}({})", num_vars, to_hex(num_vars, table))
}

/// Binary string representation of the function
pub fn to_bin(num_vars: usize, table: &[u64]) -> String {
let width = if num_vars >= 6 { 64 } else { 1 << num_vars };
let mut s = String::new();
for t in table.iter().rev() {
write!(f, "{:0width$x}", t)?;
s.push_str(&format!("{:0width$b}", t));
}
write!(f, ")")
s
}

/// Binary formatting
Expand All @@ -257,13 +277,33 @@ pub fn fmt_bin(
table: &[u64],
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
let i = num_vars;
write!(f, "Lut{:}(", i)?;
let width = if i >= 6 { 64 } else { 1 << i };
for t in table.iter().rev() {
write!(f, "{:0width$b}", t)?;
write!(f, "Lut{:}({})", num_vars, to_bin(num_vars, table))
}

/// Fill from the hexadecimal representation
pub fn fill_hex(num_vars: usize, table: &mut [u64], s: &str) -> Result<(), ()> {
debug_assert_eq!(table.len(), table_size(num_vars));
if !s.is_ascii() {
return Err(());
}
let width = hex_str_size(num_vars);
if s.len() != width * table.len() {
return Err(());
}

for (i, t) in table.iter_mut().rev().enumerate() {
let ss = &s[i * width..(i + 1) * width];
let v = u64::from_str_radix(ss, 16);
match v {
Ok(v) => {
*t = v;
}
Err(_) => {
return Err(());
}
}
}
write!(f, ")")
Ok(())
}

/// Swap two variables in the LUT
Expand Down
48 changes: 48 additions & 0 deletions src/static_lut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,27 @@ impl<const N: usize, const T: usize> StaticLut<N, T> {
}
table_complexity(N, table.as_slice())
}

/// Return the hexadecimal string representing the function
///
/// Contrary to display, nothing else in printed: `a45b` instead of `Lut4(a45b)`
pub fn to_hex_string(&self) -> String {
to_hex(self.num_vars(), self.table.as_ref())
}

/// Return the binary string representing the function
///
/// Contrary to display, nothing else in printed: `0101` instead of `Lut2(0101)`
pub fn to_bin_string(&self) -> String {
to_bin(self.num_vars(), self.table.as_ref())
}

/// Build a Lut from an hexadecimal string
pub fn from_hex_string(s: &str) -> Result<Self, ()> {

Check warning on line 359 in src/static_lut.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

this returns a `Result<_, ()>`

warning: this returns a `Result<_, ()>` --> src/static_lut.rs:359:5 | 359 | pub fn from_hex_string(s: &str) -> Result<Self, ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use a custom `Error` type instead = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#result_unit_err
let mut ret = Self::zero();
fill_hex(ret.num_vars(), ret.table.as_mut(), s)?;
Ok(ret)
}
}

#[doc(hidden)]
Expand Down Expand Up @@ -767,4 +788,31 @@ mod tests {
assert_eq!(lut, Lut6::from(u64::from(lut)));
}
}

#[test]
#[cfg(feature = "rand")]
fn test_string_conversion() {
use crate::Lut8;

for _ in 0..10 {
let lut = Lut0::random();
assert_eq!(lut, Lut0::from_hex_string(&lut.to_hex_string()).unwrap());
}
for _ in 0..10 {
let lut = Lut1::random();
assert_eq!(lut, Lut1::from_hex_string(&lut.to_hex_string()).unwrap());
}
for _ in 0..10 {
let lut = Lut2::random();
assert_eq!(lut, Lut2::from_hex_string(&lut.to_hex_string()).unwrap());
}
for _ in 0..10 {
let lut = Lut3::random();
assert_eq!(lut, Lut3::from_hex_string(&lut.to_hex_string()).unwrap());
}
for _ in 0..10 {
let lut = Lut8::random();
assert_eq!(lut, Lut8::from_hex_string(&lut.to_hex_string()).unwrap());
}
}
}

0 comments on commit f4b3784

Please sign in to comment.