Skip to content

Commit e19b674

Browse files
committed
FormatSpec got a preconversor:FormatPreconversor to handle !r, !s and !a
1 parent 65d0093 commit e19b674

1 file changed

Lines changed: 41 additions & 2 deletions

File tree

vm/src/format.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,24 @@ use num_traits::Signed;
33
use std::cmp;
44
use std::str::FromStr;
55

6+
#[derive(Debug, Copy, Clone, PartialEq)]
7+
pub enum FormatPreconversor {
8+
Str,
9+
Repr,
10+
Ascii,
11+
}
12+
13+
impl FormatPreconversor {
14+
fn from_char(c: char) -> Option<FormatPreconversor> {
15+
match c {
16+
's' => Some(FormatPreconversor::Str),
17+
'r' => Some(FormatPreconversor::Repr),
18+
'a' => Some(FormatPreconversor::Ascii),
19+
_ => None,
20+
}
21+
}
22+
}
23+
624
#[derive(Debug, Copy, Clone, PartialEq)]
725
pub enum FormatAlign {
826
Left,
@@ -56,6 +74,7 @@ pub enum FormatType {
5674

5775
#[derive(Debug, PartialEq)]
5876
pub struct FormatSpec {
77+
preconversor: Option<FormatPreconversor>,
5978
fill: Option<char>,
6079
align: Option<FormatAlign>,
6180
sign: Option<FormatSign>,
@@ -75,6 +94,23 @@ fn get_num_digits(text: &str) -> usize {
7594
text.len()
7695
}
7796

97+
fn parse_preconversor(text: &str) -> (Option<FormatPreconversor>, &str) {
98+
let mut chars = text.chars();
99+
if chars.next() != Some('!') {
100+
return (None, text);
101+
}
102+
103+
match chars.next() {
104+
None => (None, text), // Should fail instead?
105+
Some(c) => {
106+
match FormatPreconversor::from_char(c) {
107+
Some(preconversor) => (Some(preconversor), chars.as_str()),
108+
None => (None, text), // Should fail instead?
109+
}
110+
},
111+
}
112+
}
113+
78114
fn parse_align(text: &str) -> (Option<FormatAlign>, &str) {
79115
let mut chars = text.chars();
80116
let maybe_align = chars.next().and_then(FormatAlign::from_char);
@@ -186,7 +222,8 @@ fn parse_format_type(text: &str) -> (Option<FormatType>, &str) {
186222
}
187223

188224
fn parse_format_spec(text: &str) -> FormatSpec {
189-
let (fill, align, after_align) = parse_fill_and_align(text);
225+
let (preconversor, after_preconversor) = parse_preconversor(text);
226+
let (fill, align, after_align) = parse_fill_and_align(after_preconversor);
190227
let (sign, after_sign) = parse_sign(after_align);
191228
let (alternate_form, after_alternate_form) = parse_alternate_form(after_sign);
192229
let after_zero = parse_zero(after_alternate_form);
@@ -196,6 +233,7 @@ fn parse_format_spec(text: &str) -> FormatSpec {
196233
let (format_type, _) = parse_format_type(after_precision);
197234

198235
FormatSpec {
236+
preconversor,
199237
fill,
200238
align,
201239
sign,
@@ -473,10 +511,11 @@ impl FormatString {
473511
let arg_part = parts[0];
474512

475513
let preconversor_spec = if parts.len() > 1 {
476-
parts[1].to_string()
514+
"!".to_string() + parts[1]
477515
} else {
478516
String::new()
479517
};
518+
let format_spec = preconversor_spec + &format_spec;
480519

481520
if arg_part.is_empty() {
482521
return Ok(FormatPart::AutoSpec(format_spec));

0 commit comments

Comments
 (0)