use crate::Rational;
use crate::gaussian_rational::GaussianRational;
use alloc::string::String;
use core::str::FromStr;
use malachite_base::num::basic::traits::Zero;
fn parse_imaginary_term(s: &str) -> Result<Rational, ()> {
let j = s.find('i').ok_or(())?;
let numerator = &s[..j];
let rest = &s[j + 1..];
if numerator.contains('/') || !rest.is_empty() && !rest.starts_with('/') {
return Err(());
}
let mut rational_string = String::with_capacity(s.len());
rational_string.push_str(numerator);
if matches!(numerator, "" | "+" | "-") {
rational_string.push('1');
}
rational_string.push_str(rest);
Rational::from_str(&rational_string)
}
impl FromStr for GaussianRational {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
let Some(i_index) = s.find('i') else {
return Ok(Self {
real: Rational::from_str(s)?,
imaginary: Rational::ZERO,
});
};
match s[..i_index].rfind(['+', '-']).filter(|&k| k != 0) {
None => Ok(Self {
real: Rational::ZERO,
imaginary: parse_imaginary_term(s)?,
}),
Some(k) => Ok(Self {
real: Rational::from_str(&s[..k])?,
imaginary: parse_imaginary_term(&s[k..])?,
}),
}
}
}