mod constants;
use core::cmp::Ordering;
pub use constants::{BTRIT_0, BTRIT_1, BTRIT_NEG_1, UTRIT_0, UTRIT_1, UTRIT_2, UTRIT_U384_MAX, UTRIT_U384_MAX_HALF};
use crate::{
encoding::ternary::{Btrit, ShiftTernary, T1B1Buf, Trit, TritBuf, Utrit},
hashes::ternary::kerl::bigint::{
binary_representation::{U32Repr, U8Repr},
endianness::{BigEndian, LittleEndian},
I384, T242, U384,
},
};
def_and_impl_ternary!(T243, 243);
impl<T: Trit> T243<T> {
pub fn into_t242(self) -> T242<T> {
let mut trit_buf = self.into_inner();
trit_buf.pop();
T242::new(trit_buf)
}
}
impl T243<Utrit> {
pub fn from_u384(value: U384<BigEndian, U32Repr>) -> Self {
let mut u384_value = value;
let mut u384_inner_slice = &mut u384_value.inner[..];
let mut trit_buf = T243::<Utrit>::zero().into_inner();
unsafe {
for trit in trit_buf.as_i8_slice_mut() {
let mut rem = 0;
let mut first_digit = 0;
for (i, digit) in u384_inner_slice.iter().enumerate() {
first_digit = i;
if *digit != 0 {
break;
}
}
u384_inner_slice = &mut u384_inner_slice[first_digit..];
for digit in u384_inner_slice.iter_mut() {
let digit_with_rem = (u64::from(rem) << 32) | u64::from(*digit);
#[allow(clippy::cast_possible_truncation)]
{
*digit = (digit_with_rem / 3u64) as u32;
rem = (digit_with_rem % 3u64) as u32;
}
}
#[allow(clippy::cast_possible_truncation)] {
*trit = rem as i8;
}
}
}
Self(trit_buf)
}
}
impl<T: Trit> From<T242<T>> for T243<T> {
fn from(value: T242<T>) -> Self {
value.into_t243()
}
}
impl From<I384<BigEndian, U8Repr>> for T243<Btrit> {
fn from(value: I384<BigEndian, U8Repr>) -> Self {
let be_u32 = Into::<I384<BigEndian, U32Repr>>::into(value);
let le_u32 = Into::<I384<LittleEndian, U32Repr>>::into(be_u32);
le_u32.into()
}
}
impl From<I384<BigEndian, U32Repr>> for T243<Btrit> {
fn from(value: I384<BigEndian, U32Repr>) -> Self {
let value_little_endian: I384<LittleEndian, U32Repr> = value.into();
value_little_endian.into()
}
}
impl From<I384<LittleEndian, U32Repr>> for T243<Btrit> {
fn from(value: I384<LittleEndian, U32Repr>) -> Self {
let u384_value = value.shift_into_u384();
let t243_unbalanced = T243::<Utrit>::from(u384_value);
t243_unbalanced.into_shifted()
}
}
impl From<U384<BigEndian, U32Repr>> for T243<Utrit> {
fn from(value: U384<BigEndian, U32Repr>) -> Self {
Self::from_u384(value)
}
}
impl From<U384<LittleEndian, U32Repr>> for T243<Utrit> {
fn from(value: U384<LittleEndian, U32Repr>) -> Self {
let value: U384<BigEndian, U32Repr> = value.into();
value.into()
}
}