use num::{BigInt, BigRational, BigUint, Rational32};
use crate::{
divisible::Prime,
error::AdicResult,
num_adic::{IAdic, RAdic, UAdic},
traits::{AdicInteger, AdicPrimitive, HasDigitDisplay},
};
use super::IntegerVariant;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct EAdic {
pub (super) variant: IntegerVariant,
}
impl EAdic {
pub fn new<P>(p: P, init_digits: Vec<u32>) -> Self
where P: Into<Prime> {
Self {
variant: UAdic::new(p, init_digits).into()
}
}
pub fn new_neg<P>(p: P, init_digits: Vec<u32>) -> Self
where P: Into<Prime> {
Self {
variant: IAdic::new_neg(p, init_digits).into()
}
}
pub fn new_repeating<P>(p: P, fix_d: Vec<u32>, rep_d: Vec<u32>) -> Self
where P: Into<Prime> {
Self {
variant: RAdic::new(p, fix_d, rep_d).into()
}
}
pub fn u32_value(&self) -> AdicResult<u32> {
let uadic = match &self.variant {
IntegerVariant::Unsigned(u) => u,
IntegerVariant::Signed(i) => &UAdic::try_from(i.clone())?,
IntegerVariant::Rational(r) => &UAdic::try_from(r.clone())?,
};
uadic.u32_value()
}
pub fn bigint_value(&self) -> AdicResult<BigUint> {
let uadic = match &self.variant {
IntegerVariant::Unsigned(u) => u,
IntegerVariant::Signed(i) => &UAdic::try_from(i.clone())?,
IntegerVariant::Rational(r) => &UAdic::try_from(r.clone())?,
};
Ok(uadic.bigint_value())
}
pub fn i32_value(&self) -> AdicResult<i32> {
let iadic = match &self.variant {
IntegerVariant::Unsigned(u) => &IAdic::from(u.clone()),
IntegerVariant::Signed(i) => i,
IntegerVariant::Rational(r) => &IAdic::try_from(r.clone())?,
};
iadic.i32_value()
}
pub fn signed_bigint_value(&self) -> AdicResult<BigInt> {
let iadic = match &self.variant {
IntegerVariant::Unsigned(u) => &IAdic::from(u.clone()),
IntegerVariant::Signed(i) => i,
IntegerVariant::Rational(r) => &IAdic::try_from(r.clone())?,
};
Ok(iadic.signed_bigint_value())
}
pub fn rational_value(&self) -> AdicResult<Rational32> {
RAdic::from(self.clone()).rational_value()
}
pub fn big_rational_value(&self) -> BigRational {
RAdic::from(self.clone()).big_rational_value()
}
#[allow(dead_code)]
pub (crate) fn into_raw(self) -> IntegerVariant {
self.variant
}
#[allow(dead_code)]
pub (crate) fn raw(&self) -> &IntegerVariant {
&self.variant
}
#[allow(dead_code)]
pub (crate) fn mut_raw(&mut self) -> &mut IntegerVariant {
&mut self.variant
}
}
impl AdicPrimitive for EAdic {
fn zero<P>(p: P) -> Self
where P: Into<Prime> {
Self::from(UAdic::zero(p))
}
fn one<P>(p: P) -> Self
where P: Into<Prime> {
Self::from(UAdic::one(p))
}
fn p(&self) -> Prime {
match &self.variant {
IntegerVariant::Unsigned(u) => u.p(),
IntegerVariant::Signed(i) => i.p(),
IntegerVariant::Rational(r) => r.p(),
}
}
}
impl AdicInteger for EAdic { }
impl HasDigitDisplay for EAdic {
type DigitDisplay = String;
fn digit_display(&self) -> String {
match &self.variant {
IntegerVariant::Unsigned(u) => u.digit_display(),
IntegerVariant::Signed(i) => i.digit_display(),
IntegerVariant::Rational(r) => r.digit_display(),
}
}
}