use crate::{
divisible::Divisible,
error::AdicError,
traits::{AdicPrimitive, HasDigits},
};
use super::{
IAdic, RAdic, Sign, UAdic,
};
impl From<UAdic> for IAdic {
fn from(a: UAdic) -> Self {
IAdic::new_pos(a.p(), a.digits_vec())
}
}
impl From<UAdic> for RAdic {
fn from(value: UAdic) -> Self {
Self::new(value.p(), value.digits_vec(), vec![])
}
}
impl TryFrom<IAdic> for UAdic {
type Error = AdicError;
fn try_from(a: IAdic) -> Result<Self, Self::Error> {
match a.sign {
Sign::Pos => Ok(UAdic::new(a.p(), a.digits().collect())),
Sign::Neg => Err(AdicError::BadConversion),
}
}
}
impl From<IAdic> for RAdic {
fn from(a: IAdic) -> Self {
let p = a.p();
if a.has_finite_digits() {
Self::new(p, a.digits().collect(), vec![])
} else {
let num_non_trailing = a.num_non_trailing();
Self::new(p, a.digits().take(num_non_trailing).collect(), vec![p.m1()])
}
}
}
impl TryFrom<RAdic> for UAdic {
type Error = AdicError;
fn try_from(a: RAdic) -> Result<Self, Self::Error> {
let p = a.p();
if a.repeat_digits().next().is_none() {
Ok(Self::new(p, a.into_fixed_digits().collect()))
} else {
Err(AdicError::BadConversion)
}
}
}
impl TryFrom<RAdic> for IAdic {
type Error = AdicError;
fn try_from(a: RAdic) -> Result<Self, Self::Error> {
let p = a.p();
let mut repeat_iter = a.repeat_digits();
match repeat_iter.next() {
None => Ok(Self::new_pos(p, a.fixed_digits().collect::<Vec<_>>())),
Some(digit) => {
if repeat_iter.next().is_none() && digit == a.p().m1() {
Ok(Self::new_neg(p, a.fixed_digits().collect::<Vec<_>>()))
} else {
Err(AdicError::BadConversion)
}
}
}
}
}