use crate::gaussian_integer::GaussianInteger;
use crate::integer::Integer;
use core::str::FromStr;
use malachite_base::num::basic::traits::{NegativeOne, One, Zero};
fn parse_lone_imaginary_coefficient(s: &str) -> Result<Integer, ()> {
match s {
"" | "+" => Ok(Integer::ONE),
"-" => Ok(Integer::NEGATIVE_ONE),
_ => Integer::from_str(s),
}
}
fn parse_joined_imaginary_coefficient(s: &str) -> Result<Integer, ()> {
match s {
"+" => Ok(Integer::ONE),
"-" => Ok(Integer::NEGATIVE_ONE),
_ => {
if let Some(digits) = s.strip_prefix('+') {
Integer::from_str(digits)
} else {
Integer::from_str(s)
}
}
}
}
impl FromStr for GaussianInteger {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
let Some(r) = s.strip_suffix('i') else {
return Ok(Self {
real: Integer::from_str(s)?,
imaginary: Integer::ZERO,
});
};
match r.rfind(['+', '-']).filter(|&k| k != 0) {
None => Ok(Self {
real: Integer::ZERO,
imaginary: parse_lone_imaginary_coefficient(r)?,
}),
Some(k) => Ok(Self {
real: Integer::from_str(&r[..k])?,
imaginary: parse_joined_imaginary_coefficient(&r[k..])?,
}),
}
}
}