Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 1.93 KB | None | 0 0
  1. pub use self::Error::ParseValueError;
  2. pub use self::Error::ValueTooLargeError;
  3.  
  4. use base::Base;
  5. use num::pow::checked_pow;
  6. use num::ToPrimitive;
  7.  
  8. #[derive(Debug)]
  9. #[derive(PartialEq)]
  10. pub struct Literal {
  11.     width: u8,
  12.     value: u64,
  13. }
  14.  
  15. #[derive(Debug)]
  16. #[derive(PartialEq)]
  17. pub enum Error {
  18.     ParseValueError,
  19.     ValueTooLargeError,
  20. }
  21.  
  22. impl Literal {
  23.     pub fn new(base: &Base, chars: &str) -> Result<Literal, Error> {
  24.         let radix = match *base {
  25.             Base::Binary => 2u32,
  26.             Base::Octal => 8u32,
  27.             Base::Hexadecimal => 16u32,
  28.         };
  29.  
  30.         let value = {
  31.             if let Ok(value) = u64::from_str_radix(chars, radix) {
  32.                 value
  33.             } else {
  34.                 return Err(ParseValueError);
  35.             }
  36.         };
  37.  
  38.         let width = {
  39.             let digits = chars.len();
  40.  
  41.             if let Some(max) = checked_pow(radix as u64, digits) {
  42.                 let bits = (max as f64).log2().ceil();
  43.  
  44.                 if let Some(result) = bits.to_u8() {
  45.                     result
  46.                 } else {
  47.                     return Err(ValueTooLargeError);
  48.                 }
  49.             } else {
  50.                 return Err(ValueTooLargeError);
  51.             }
  52.         };
  53.  
  54.         let result = Literal {
  55.             width: width,
  56.             value: value,
  57.         };
  58.  
  59.         Ok(result)
  60.     }
  61. }
  62.  
  63. #[cfg(test)]
  64. mod tests {
  65.     use base::Base;
  66.     use literal::Literal;
  67.  
  68.     #[test]
  69.     fn new_from_base_str() {
  70.         let values = [(Base::Binary, "01001101101", 11, 0x26D),
  71.                       (Base::Octal, "74053740", 24, 0xF057E0),
  72.                       (Base::Hexadecimal, "00BADAB0DE", 40, 0xBADAB0DE)];
  73.  
  74.         for value in values.iter() {
  75.             let literal = Literal::new(&value.0, value.1).unwrap();
  76.  
  77.             assert_eq!(literal.width, value.2);
  78.             assert_eq!(literal.value, value.3);
  79.         }
  80.     }
  81. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement