utils.rs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. use std::error::Error;
  2. use std::fmt;
  3. #[derive(Debug)]
  4. pub enum ConversionError {
  5. StringTooLong(usize),
  6. StringTooShort(usize),
  7. VecLengthMismatch { expected: usize, actual: usize },
  8. InvalidUtf8,
  9. }
  10. impl fmt::Display for ConversionError {
  11. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  12. match self {
  13. ConversionError::StringTooLong(len) => {
  14. write!(f, "String length {} exceeds 32 bytes", len)
  15. }
  16. ConversionError::StringTooShort(len) => {
  17. write!(f, "String length {} is less than 32 bytes", len)
  18. }
  19. ConversionError::VecLengthMismatch { expected, actual } => {
  20. write!(
  21. f,
  22. "Vector length mismatch: expected {}, got {}",
  23. expected, actual
  24. )
  25. }
  26. ConversionError::InvalidUtf8 => write!(f, "Invalid UTF-8 sequence in bytes"),
  27. }
  28. }
  29. }
  30. impl Error for ConversionError {}
  31. // Convert string to bytes with padding
  32. pub fn string_to_bytes32_padded(input: &str) -> Result<[u8; 32], ConversionError> {
  33. let bytes = input.as_bytes();
  34. let len = bytes.len();
  35. if len > 32 {
  36. return Err(ConversionError::StringTooLong(len));
  37. }
  38. let mut result = [0u8; 32];
  39. result[..len].copy_from_slice(bytes);
  40. Ok(result)
  41. }
  42. // Convert bytes back to string, trimming trailing zeros
  43. pub fn bytes32_to_string(bytes: &[u8; 32]) -> Result<String, ConversionError> {
  44. // Find the actual length by looking for the first zero or taking full length
  45. let actual_len = bytes.iter().position(|&b| b == 0).unwrap_or(32);
  46. // Convert the slice up to actual_len to a string
  47. String::from_utf8(bytes[..actual_len].to_vec()).map_err(|_| ConversionError::InvalidUtf8)
  48. }
  49. // Convert vec of strings to byte arrays with padding
  50. pub fn strings_to_bytes32_array_padded<const N: usize>(
  51. inputs: Vec<&str>,
  52. ) -> Result<[[u8; 32]; N], ConversionError> {
  53. if inputs.len() != N {
  54. return Err(ConversionError::VecLengthMismatch {
  55. expected: N,
  56. actual: inputs.len(),
  57. });
  58. }
  59. let mut result = [[0u8; 32]; N];
  60. for (i, input) in inputs.iter().enumerate() {
  61. result[i] = string_to_bytes32_padded(input)?;
  62. }
  63. Ok(result)
  64. }
  65. // Convert array of byte arrays back to vec of strings
  66. pub fn bytes32_array_to_strings<const N: usize>(
  67. bytes_array: &[[u8; 32]; N],
  68. ) -> Result<Vec<String>, ConversionError> {
  69. let mut result = Vec::with_capacity(N);
  70. for bytes in bytes_array.iter() {
  71. result.push(bytes32_to_string(bytes)?);
  72. }
  73. Ok(result)
  74. }