rustpython_literal/
complex.rs1use crate::float;
2use alloc::borrow::ToOwned;
3use alloc::string::{String, ToString};
4
5pub fn to_string(re: f64, im: f64) -> String {
7 let mut im_part = if im.fract() == 0.0 {
9 im.to_string()
10 } else {
11 float::to_string(im)
12 };
13 im_part.push('j');
14
15 let re_part = if re == 0.0 {
17 if re.is_sign_positive() {
18 return im_part;
19 } else {
20 "-0".to_owned()
21 }
22 } else if re.fract() == 0.0 {
23 re.to_string()
24 } else {
25 float::to_string(re)
26 };
27 let mut result =
28 String::with_capacity(re_part.len() + im_part.len() + 2 + im.is_sign_positive() as usize);
29 result.push('(');
30 result.push_str(&re_part);
31 if im.is_sign_positive() || im.is_nan() {
32 result.push('+');
33 }
34 result.push_str(&im_part);
35 result.push(')');
36 result
37}
38
39pub fn parse_str(s: &str) -> Option<(f64, f64)> {
43 let s = s.trim();
44 let s = match s.strip_prefix('(') {
46 None => s,
47 Some(s) => s.strip_suffix(')')?.trim(),
48 };
49
50 let value = match s.strip_suffix(|c| c == 'j' || c == 'J') {
51 None => (float::parse_str(s)?, 0.0),
52 Some(mut s) => {
53 let mut real = 0.0;
54 for (i, w) in s.as_bytes().windows(2).enumerate() {
56 if (w[1] == b'+' || w[1] == b'-') && !(w[0] == b'e' || w[0] == b'E') {
57 real = float::parse_str(&s[..=i])?;
58 s = &s[i + 1..];
59 break;
60 }
61 }
62
63 let imag = match s {
64 "" | "+" => 1.0,
66 "-" => -1.0,
68 s => float::parse_str(s)?,
69 };
70
71 (real, imag)
72 }
73 };
74 Some(value)
75}