use crate::translate::{
bct_trybble_to_i8,
i8_trybble_to_bct,
bct_trybble_to_ternary_string,
i16_tryte_to_nonary_string,
};
#[derive(Debug)]
pub struct Tryte {
hi: u8,
lo: u8,
}
impl Clone for Tryte {
fn clone(&self) -> Self {
Tryte {
hi: self.hi,
lo: self.lo,
}
}
}
impl Tryte {
pub fn from_bct_trybbles(hi: u8, lo: u8) -> Self {
Tryte { hi, lo }
}
pub fn hi_value(&self) -> i8 {
bct_trybble_to_i8(self.hi)
}
pub fn lo_value(&self) -> i8 {
bct_trybble_to_i8(self.lo)
}
pub fn hi_bct(&self) -> u8 {
self.hi
}
pub fn lo_bct(&self) -> u8 {
self.lo
}
pub fn to_integer(&self) -> i16 {
let low = bct_trybble_to_i8(self.lo) as i16;
let high = bct_trybble_to_i8(self.hi) as i16;
(high * 27) + low
}
pub fn as_ternary_string(&self) -> Option<String> {
let hi_opt = bct_trybble_to_ternary_string(self.hi);
let lo_opt = bct_trybble_to_ternary_string(self.lo);
match (hi_opt, lo_opt) {
(Some(hi), Some(lo)) => Some([hi, lo].concat()),
_ => None,
}
}
pub fn as_nonary_string(&self) -> Option<String> {
i16_tryte_to_nonary_string(self.to_integer())
}
pub fn add(first: &Tryte, second: &Tryte) -> (Tryte, i8) {
let result = first.to_integer() + second.to_integer();
let tryte = Tryte::from(result);
let carry = 0;
(tryte, carry)
}
pub fn sub(first: &Tryte, second: &Tryte) -> (Tryte, i8) {
let result = first.to_integer() - second.to_integer();
let tryte = Tryte::from(result);
let carry = 0;
(tryte, carry)
}
}
impl Into<i16> for Tryte {
fn into(self) -> i16 {
self.to_integer()
}
}
impl From<i16> for Tryte {
fn from(number: i16) -> Self {
let res = (number / 27) as i8;
let rem = (number % 27) as i8;
let (high, low) = if rem > 13 {
(res + 1, rem - 27)
} else if rem < -13 {
(res - 1, rem + 27)
} else {
(res, rem)
};
Tryte {
hi: i8_trybble_to_bct(high),
lo: i8_trybble_to_bct(low),
}
}
}