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
use crate::tryte::Tryte;

#[derive(Debug)]
pub struct Word {
  hi: Tryte,
  lo: Tryte,
}

impl Clone for Word {
  fn clone(&self) -> Self {
    Word {
      hi: self.hi.clone(),
      lo: self.lo.clone(),
    }
  }
}

impl Word {
  pub fn from_trytes(hi: Tryte, lo: Tryte) -> Self {
    Word { hi, lo }
  }

  pub fn hi_tryte(&self) -> &Tryte {
    &self.hi
  }

  pub fn lo_tryte(&self) -> &Tryte {
    &self.lo
  }
}

const SHIFT: i16 = 729;
const HALF_SHIFT: i16 = 364;

impl Into<i32> for Word {
  fn into(self) -> i32 {
    let low: i16 = self.lo.into();
    let high: i16 = self.hi.into();
    (high as i32 * SHIFT as i32) + low as i32
  }
}

impl From<i32> for Word {
  fn from(number: i32) -> Self {
    let res = (number / SHIFT as i32) as i16;
    let rem = (number % SHIFT as i32) as i16;
    let (high, low) = if rem > HALF_SHIFT {
      (res + 1, rem - SHIFT)
    } else if rem < -HALF_SHIFT {
      (res - 1, rem + SHIFT)
    } else {
      (res, rem)
    };
    Word {
      hi: Tryte::from(high),
      lo: Tryte::from(low),
    }
  }
}