use std::fmt::{Display, Formatter};
use num_bigint::BigInt;
use serde::{Deserialize, Serialize};
use crate::utils::deserialize_id;
use crate::Factor;
#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Number {
#[serde(deserialize_with = "deserialize_id")]
id: BigInt,
status: NumberStatus,
factors: Vec<Factor>,
}
impl Number {
pub fn id(&self) -> &BigInt {
&self.id
}
pub fn status(&self) -> &NumberStatus {
&self.status
}
pub fn factors(&self) -> &Vec<Factor> {
&self.factors
}
pub fn is_prime(&self) -> bool {
self.status == NumberStatus::DefinitelyPrime || self.status == NumberStatus::ProbablyPrime
}
pub fn is_definitely_prime(&self) -> bool {
self.status == NumberStatus::DefinitelyPrime
}
pub fn unique_factors(&self) -> Vec<&BigInt> {
self.factors.iter().map(|f| f.base()).collect()
}
pub fn into_unique_factors(self) -> Vec<BigInt> {
let mut factors: Vec<BigInt> = self
.factors
.into_iter()
.map(|f| f.base().to_owned())
.collect();
factors.sort_unstable();
factors
}
pub fn into_factors_flattened(self) -> Vec<BigInt> {
let mut factors: Vec<BigInt> = self.factors.clone().into_iter().flatten().collect();
factors.sort_unstable();
factors
}
}
impl Display for Number {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let factor_strings: Vec<String> = self
.clone()
.into_factors_flattened()
.iter()
.map(|n| n.to_string())
.collect();
write!(f, "{}", factor_strings.join(" "))
}
}
#[derive(Deserialize, Serialize, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum NumberStatus {
#[serde(rename = "C")]
NoFactorsKnown,
#[serde(rename = "CF")]
FactorsKnown,
#[serde(rename = "FF")]
FullyFactored,
#[serde(rename = "P")]
DefinitelyPrime,
#[serde(rename = "Prp")]
#[serde(alias = "PRP")]
ProbablyPrime,
#[serde(rename = "U")]
Unknown,
Unit,
Zero,
#[serde(rename = "N")]
NotInDatabase,
}