diff --git a/complex/src/lib.rs b/complex/src/lib.rs index 8281b68..62ff99a 100644 --- a/complex/src/lib.rs +++ b/complex/src/lib.rs @@ -743,12 +743,12 @@ impl fmt::Binary for Complex where } impl FromStr for Complex where - T: FromStr + Num + PartialOrd + Clone + std::fmt::Debug, T::Err: Error + PartialEq + T: FromStr + Num + PartialOrd + Clone, T::Err: Error { - type Err = ParseComplexError; + type Err = ParseComplexError; /// Parses `a +/- bi`; `ai +/- b`; `a`; or `bi` where `a` and `b` are of type `T` - fn from_str(s: &str) -> Result, ParseComplexError> + fn from_str(s: &str) -> Result, ParseComplexError> { let imag = match s.rfind('j') { None => 'i', @@ -758,46 +758,38 @@ impl FromStr for Complex where let mut b = String::with_capacity(s.len()); let mut first = true; - let mut char_indices = s.char_indices(); + let char_indices = s.char_indices(); let mut pc = ' '; let mut split_index = s.len(); - loop { - match char_indices.next() { - Some(t) => { - let i = t.0; - let cc = t.1; - - if cc == '+' && pc != 'e' && pc != 'E' { - // ignore '+' if part of an exponent - if first { - split_index = i; - first = false; - } - // don't carry '+' over into b - pc = ' '; - continue; - } else if cc == '-' && pc != 'e' && pc != 'E' && i > 0 { - // ignore '-' if part of an exponent or begins the string - if first { - split_index = i; - first = false; - } - // DO carry '-' over into b - } - - if pc == '-' && cc == ' ' && !first { - // ignore whitespace between minus sign and next number - continue; - } - - if !first { - b.push(cc); - } - pc = cc; - }, - None => break, + for (i, cc) in char_indices { + if cc == '+' && pc != 'e' && pc != 'E' && i > 0 { + // ignore '+' if part of an exponent + if first { + split_index = i; + first = false; + } + // don't carry '+' over into b + pc = ' '; + continue; + } else if cc == '-' && pc != 'e' && pc != 'E' && i > 0 { + // ignore '-' if part of an exponent or begins the string + if first { + split_index = i; + first = false; + } + // DO carry '-' over into b } + + if pc == '-' && cc == ' ' && !first { + // ignore whitespace between minus sign and next number + continue; + } + + if !first { + b.push(cc); + } + pc = cc; } // split off real and imaginary parts, trim whitespace @@ -833,6 +825,8 @@ impl FromStr for Complex where im = "1"; } else if im == "-" { im = "-1"; + } else if im == "+" { + im = "1"; } // parse im @@ -867,38 +861,38 @@ impl serde::Deserialize for Complex where } #[derive(Debug, PartialEq)] -pub struct ParseComplexError where - T: FromStr + std::fmt::Debug + PartialEq, T::Err: Error + PartialEq +pub struct ParseComplexError where + E: Error { - kind: ComplexErrorKind, + kind: ComplexErrorKind, } #[derive(Debug, PartialEq)] -enum ComplexErrorKind where - T: FromStr + std::fmt::Debug + PartialEq, T::Err: Error + PartialEq +enum ComplexErrorKind where + E: Error { - ParseError(T::Err), + ParseError(E), ExprError } -impl Error for ParseComplexError where - T: FromStr + std::fmt::Debug + PartialEq, T::Err: Error + PartialEq +impl Error for ParseComplexError where + E: Error { fn description(&self) -> &str { self.kind.description() } } -impl fmt::Display for ParseComplexError where - T: FromStr + std::fmt::Debug + PartialEq, T::Err: Error + PartialEq +impl fmt::Display for ParseComplexError where + E: Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.description().fmt(f) } } -impl ComplexErrorKind where - T: FromStr + std::fmt::Debug + PartialEq, T::Err: Error + PartialEq +impl ComplexErrorKind where + E: Error { fn description(&self) -> &str { match *self { @@ -1560,12 +1554,13 @@ mod test { test(_0_0i, "-0"); test(_0_0i, "0i"); test(_0_0i, "0j"); + test(_0_0i, "+0j"); test(_0_0i, "-0i"); test(_1_0i, "1 + 0i"); test(_1_0i, "1+0j"); test(_1_0i, "1 - 0j"); - test(_1_0i, "1-0i"); + test(_1_0i, "+1-0i"); test(_1_0i, "-0j+1"); test(_1_0i, "1"); @@ -1575,7 +1570,7 @@ mod test { test(_1_1i, "1+1i"); test(_1_1i, "i + 1"); test(_1_1i, "1i+1"); - test(_1_1i, "j+1"); + test(_1_1i, "+j+1"); test(_0_1i, "0 + i"); test(_0_1i, "0+j"); @@ -1618,5 +1613,6 @@ mod test { test("314e-2ij"); test("4.3j - i"); test("1i - 2i"); + test("+ 1 - 3.0i"); } }