mirror of
https://github.com/Noratrieb/mono-fmt.git
synced 2026-01-17 08:45:05 +01:00
state machine!
This commit is contained in:
parent
6273a35732
commit
34155bcd48
2 changed files with 63 additions and 4 deletions
|
|
@ -234,6 +234,8 @@ impl ToTokens for FmtPart {
|
||||||
pub fn format_args(tokens: TokenStream) -> TokenStream {
|
pub fn format_args(tokens: TokenStream) -> TokenStream {
|
||||||
let input = parse_macro_input!(tokens as Input);
|
let input = parse_macro_input!(tokens as Input);
|
||||||
|
|
||||||
|
parser::FmtSpecParser::new(&mut input.format_str.chars().peekable()).parse();
|
||||||
|
|
||||||
let formatter = Formatter {
|
let formatter = Formatter {
|
||||||
string: input.format_str.chars().peekable(),
|
string: input.format_str.chars().peekable(),
|
||||||
exprs: input.exprs.into_iter(),
|
exprs: input.exprs.into_iter(),
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,13 @@ pub struct FmtSpec {
|
||||||
kind: FmtType,
|
kind: FmtType,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FmtSpecParser<'a> {
|
pub struct FmtSpecParser<'a> {
|
||||||
chars: &'a mut Peekable<Chars<'a>>,
|
chars: &'a mut Peekable<Chars<'a>>,
|
||||||
state: State,
|
state: State,
|
||||||
argument: FmtSpec,
|
argument: FmtSpec,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
enum State {
|
enum State {
|
||||||
Initial,
|
Initial,
|
||||||
Argument,
|
Argument,
|
||||||
|
|
@ -66,14 +66,71 @@ impl<'a> FmtSpecParser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(mut self) -> Result<FmtSpec, ()> {
|
pub fn parse(mut self) -> Result<FmtSpec, ()> {
|
||||||
while self.state != State::Done {
|
while self.state != State::Done {
|
||||||
self.step()?;
|
self.step()?;
|
||||||
}
|
}
|
||||||
Ok(self.argument)
|
Ok(self.argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<char> {
|
||||||
|
self.chars.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn peek(&mut self) -> Option<char> {
|
||||||
|
self.chars.peek().copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eat(&mut self, char: char) -> bool {
|
||||||
|
if self.peek() == Some(char) {
|
||||||
|
self.next();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eat_until(&mut self, char: char) -> Option<String> {
|
||||||
|
let mut string = String::new();
|
||||||
|
let mut has_char = false;
|
||||||
|
while self.peek() != Some(char) {
|
||||||
|
self.next();
|
||||||
|
string.push(char);
|
||||||
|
has_char = true;
|
||||||
|
}
|
||||||
|
has_char.then_some(string)
|
||||||
|
}
|
||||||
|
|
||||||
fn step(&mut self) -> Result<(), ()> {
|
fn step(&mut self) -> Result<(), ()> {
|
||||||
todo!()
|
match self.state {
|
||||||
|
State::Initial => {
|
||||||
|
let argument = if let Some(arg) = self.eat_until(':') {
|
||||||
|
if let Ok(num) = arg.parse() {
|
||||||
|
Argument::PositionalExplicit(num)
|
||||||
|
} else {
|
||||||
|
Argument::Keyword(arg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Argument::Positional
|
||||||
|
};
|
||||||
|
|
||||||
|
self.argument.arg = argument;
|
||||||
|
self.state = State::Argument;
|
||||||
|
|
||||||
|
if !self.eat(':') {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
State::Argument => todo!(),
|
||||||
|
State::Fill => todo!(),
|
||||||
|
State::Align => todo!(),
|
||||||
|
State::Sign => todo!(),
|
||||||
|
State::Zero => todo!(),
|
||||||
|
State::Width => todo!(),
|
||||||
|
State::Precision => todo!(),
|
||||||
|
State::Type => todo!(),
|
||||||
|
State::Done => unreachable!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue