1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
use super::{Scale, Prefix, PrefixFamily};

/// A decimal scale.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Decimal {
  pfx: &'static str,
  exp: i32,
}

impl Decimal {
  /// Create a new decimal prefix.
  const fn new(pfx: &'static str, exp: i32) -> Decimal {
    Decimal {
      pfx, exp
    }
  }

  pub const YOCTO: Decimal = Decimal::new("y", -24);
  pub const ZEPTO: Decimal = Decimal::new("z", -21);
  pub const ATTO: Decimal = Decimal::new("a", -18);
  pub const FEMTO: Decimal = Decimal::new("f", -15);
  pub const PICO: Decimal = Decimal::new("p", -12);
  pub const NANO: Decimal = Decimal::new("n", -9);
  pub const MICRO: Decimal = Decimal::new("μ", -6);
  pub const MILLI: Decimal = Decimal::new("m", -3);
  pub const UNIT: Decimal = Decimal::new("", 0);
  pub const KILO: Decimal = Decimal::new("k", 3);
  pub const MEGA: Decimal = Decimal::new("M", 6);
  pub const GIGA: Decimal = Decimal::new("G", 9);
  pub const TERA: Decimal = Decimal::new("T", 12);
  pub const PETA: Decimal = Decimal::new("P", 15);
  pub const EXA: Decimal = Decimal::new("E", 18);
  pub const ZETTA: Decimal = Decimal::new("Z", 21);
  pub const YOTTA: Decimal = Decimal::new("Y", 24);

  pub const AUTO: Scale<Decimal> = Scale::Auto;

  pub const ALL_PREFIXES: &'static [&'static Decimal] = &[
    &Decimal::YOCTO,
    &Decimal::ZEPTO,
    &Decimal::ATTO,
    &Decimal::FEMTO,
    &Decimal::PICO,
    &Decimal::NANO,
    &Decimal::MICRO,
    &Decimal::MILLI,
    &Decimal::UNIT,
    &Decimal::KILO,
    &Decimal::MEGA,
    &Decimal::GIGA,
    &Decimal::TERA,
    &Decimal::PETA,
    &Decimal::EXA,
    &Decimal::ZETTA,
    &Decimal::YOTTA,
  ];
}

impl Prefix for Decimal {
  #[inline]
  fn base(&self) -> i32 {
    10
  }

  #[inline]
  fn exponent(&self) -> i32 {
    self.exp
  }

  fn label(&self) -> &'static str {
    self.pfx
  }
}

impl PrefixFamily for Decimal {
  type Prefix = Decimal;

  fn unit_prefix() -> Decimal {
    Decimal::UNIT
  }

  fn all_prefixes() -> &'static [&'static Decimal] {
    Decimal::ALL_PREFIXES
  }
}

#[test]
fn test_multipliers() {
  assert_eq!(Decimal::UNIT.multiplier(), 1.0);
  assert_eq!(Decimal::KILO.multiplier(), 1000.0);
  assert_eq!(Decimal::MEGA.multiplier(), 1_000_000.0);
  assert_eq!(Decimal::GIGA.multiplier(), 1_000_000_000.0);
}

#[test]
fn test_unit_adjust() {
  assert_eq!(Decimal::UNIT.scale_value(1250), 1250.0);
}

#[test]
fn test_kilo_adjust() {
  assert_eq!(Decimal::KILO.scale_value(1250), 1.250);
}