This commit is contained in:
Michael Zhang 2021-02-22 17:51:59 -06:00
parent 0dac4f4e96
commit 3d0724e342
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
3 changed files with 50 additions and 5 deletions

View file

@ -1,2 +1,2 @@
src/builders src/builders
src/parser src/oldparser

View file

@ -97,15 +97,38 @@ fn build_resp_cond_state(pair: Pair<Rule>) -> (Status, Option<ResponseCode>, Opt
let mut code = None; let mut code = None;
let mut information = None; let mut information = None;
println!("pairs: {:#?}", pairs);
let pair = pairs.next().unwrap();
let mut pairs = pair.into_inner();
for pair in pairs { for pair in pairs {
match pair.as_rule() { match pair.as_rule() {
Rule::resp_text => information = Some(pair.as_str().to_owned()), Rule::resp_text_code => code = Some(build_resp_code(pair)),
Rule::text => information = Some(pair.as_str().to_owned()),
_ => unreachable!("{:#?}", pair), _ => unreachable!("{:#?}", pair),
} }
} }
(status, code, information) (status, code, information)
} }
fn build_resp_code(pair: Pair<Rule>) -> ResponseCode {
if !matches!(pair.as_rule(), Rule::resp_text_code) {
unreachable!("{:#?}", pair);
}
let mut pairs = pair.into_inner();
let pair = pairs.next().unwrap();
match pair.as_rule() {
Rule::resp_text_code_unseen => {
let mut pairs = pair.into_inner();
let pair = pairs.next().unwrap();
let number = pair.as_str().parse::<u32>().unwrap();
ResponseCode::Unseen(number)
}
_ => unreachable!("{:#?}", pair),
}
}
fn build_status(pair: Pair<Rule>) -> Status { fn build_status(pair: Pair<Rule>) -> Status {
match pair.as_rule() { match pair.as_rule() {
Rule::resp_status => match pair.as_str().to_uppercase().as_str() { Rule::resp_status => match pair.as_str().to_uppercase().as_str() {
@ -162,6 +185,12 @@ fn build_mailbox_data(pair: Pair<Rule>) -> MailboxData {
let flags = build_flag_list(pair); let flags = build_flag_list(pair);
MailboxData::Flags(flags) MailboxData::Flags(flags)
} }
Rule::mailbox_data_recent => {
let mut pairs = pair.into_inner();
let pair = pairs.next().unwrap();
let number = pair.as_str().parse::<u32>().unwrap();
MailboxData::Recent(number)
}
_ => unreachable!("{:#?}", pair), _ => unreachable!("{:#?}", pair),
} }
} }
@ -230,5 +259,19 @@ mod tests {
Flag::Draft, Flag::Draft,
]))) ])))
); );
assert_eq!(
parse_response("* 2 RECENT\r\n"),
Ok(Response::MailboxData(MailboxData::Recent(2)))
);
assert_eq!(
parse_response("* OK [UNSEEN 17] Message 17 is the first unseen message\r\n"),
Ok(Response::Data {
status: Status::Ok,
code: Some(ResponseCode::Unseen(17)),
information: Some("Message 17 is the first unseen message".to_owned()),
})
);
} }
} }

View file

@ -64,9 +64,10 @@ header_list = { "(" ~ header_fld_name ~ (sp ~ header_fld_name)* ~ ")" }
list_wildcards = @{ "%" | "*" } list_wildcards = @{ "%" | "*" }
literal = @{ "{" ~ number ~ "}" ~ crlf ~ char8* } literal = @{ "{" ~ number ~ "}" ~ crlf ~ char8* }
mailbox = { ^"INBOX" | astring } mailbox = { ^"INBOX" | astring }
mailbox_data = { mailbox_data_flags | (^"LIST" ~ sp ~ mailbox_list) | (^"LSUB" ~ sp ~ mailbox_list) | (^"SEARCH" ~ (sp ~ nz_number)*) | (^"STATUS" ~ sp ~ mailbox ~ sp ~ ^"(" ~ status_att_list? ~ ^")") | mailbox_data_exists | (number ~ sp ~ ^"RECENT") } mailbox_data = { mailbox_data_flags | (^"LIST" ~ sp ~ mailbox_list) | (^"LSUB" ~ sp ~ mailbox_list) | (^"SEARCH" ~ (sp ~ nz_number)*) | (^"STATUS" ~ sp ~ mailbox ~ sp ~ ^"(" ~ status_att_list? ~ ^")") | mailbox_data_exists | mailbox_data_recent }
mailbox_data_exists = { number ~ sp ~ ^"EXISTS" } mailbox_data_exists = { number ~ sp ~ ^"EXISTS" }
mailbox_data_flags = { ^"FLAGS" ~ sp ~ flag_list } mailbox_data_flags = { ^"FLAGS" ~ sp ~ flag_list }
mailbox_data_recent = { number ~ sp ~ ^"RECENT" }
mailbox_list = { "(" ~ mbx_list_flags* ~ ")" ~ sp ~ (dquote ~ quoted_char ~ dquote | nil) ~ sp ~ mailbox } mailbox_list = { "(" ~ mbx_list_flags* ~ ")" ~ sp ~ (dquote ~ quoted_char ~ dquote | nil) ~ sp ~ mailbox }
mbx_list_flags = { (mbx_list_oflag ~ sp)* ~ mbx_list_sflag ~ (sp ~ mbx_list_oflag)* | mbx_list_oflag ~ (sp ~ mbx_list_oflag)* } mbx_list_flags = { (mbx_list_oflag ~ sp)* ~ mbx_list_sflag ~ (sp ~ mbx_list_oflag)* | mbx_list_oflag ~ (sp ~ mbx_list_oflag)* }
mbx_list_oflag = { "\\NoInferiors" | flag_extension } mbx_list_oflag = { "\\NoInferiors" | flag_extension }
@ -88,10 +89,11 @@ quoted_char = @{ (!quoted_specials ~ char) | ("\\" ~ quoted_specials) }
quoted_specials = @{ dquote | "\\" } quoted_specials = @{ dquote | "\\" }
resp_cond_bye = { ^"BYE" ~ sp ~ resp_text } resp_cond_bye = { ^"BYE" ~ sp ~ resp_text }
resp_cond_state = { resp_status ~ sp ~ resp_text } resp_cond_state = { resp_status ~ sp ~ resp_text }
resp_status = { (^"OK" | ^"NO" | ^"BAD") }
resp_specials = @{ "]" } resp_specials = @{ "]" }
resp_status = { (^"OK" | ^"NO" | ^"BAD") }
resp_text = { ("[" ~ resp_text_code ~ "]" ~ sp)? ~ text } resp_text = { ("[" ~ resp_text_code ~ "]" ~ sp)? ~ text }
resp_text_code = { ^"ALERT" | (^"BADCHARSET" ~ (sp ~ "(" ~ astring ~ (sp ~ astring)* ~ ")")?) | capability_data | ^"PARSE" | (^"PERMANENTFLAGS" ~ sp ~ "(" ~ (flag_perm ~ (sp ~ flag_perm)*)? ~ ")") | ^"READ-ONLY" | ^"READ-WRITE" | ^"TRYCREATE" | (^"UIDNEXT" ~ sp ~ nz_number) | (^"UIDVALIDITY" ~ sp ~ nz_number) | (^"UNSEEN" ~ sp ~ nz_number) | (atom ~ (sp ~ resp_text_code_atom)?) } resp_text_code = { ^"ALERT" | (^"BADCHARSET" ~ (sp ~ "(" ~ astring ~ (sp ~ astring)* ~ ")")?) | capability_data | ^"PARSE" | (^"PERMANENTFLAGS" ~ sp ~ "(" ~ (flag_perm ~ (sp ~ flag_perm)*)? ~ ")") | ^"READ-ONLY" | ^"READ-WRITE" | ^"TRYCREATE" | (^"UIDNEXT" ~ sp ~ nz_number) | (^"UIDVALIDITY" ~ sp ~ nz_number) | resp_text_code_unseen | (atom ~ (sp ~ resp_text_code_atom)?) }
resp_text_code_unseen = { ^"UNSEEN" ~ sp ~ nz_number }
resp_text_code_atom = @{ (!"]" ~ text_char){1,} } resp_text_code_atom = @{ (!"]" ~ text_char){1,} }
response = { continue_req | response_data | response_done } response = { continue_req | response_data | response_done }
response_data = { "*" ~ sp ~ (resp_cond_state | resp_cond_bye | mailbox_data | message_data | capability_data) ~ crlf } response_data = { "*" ~ sp ~ (resp_cond_state | resp_cond_bye | mailbox_data | message_data | capability_data) ~ crlf }