diff options
Diffstat (limited to 'src/commands/debug/parser.rs')
-rw-r--r-- | src/commands/debug/parser.rs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/commands/debug/parser.rs b/src/commands/debug/parser.rs new file mode 100644 index 00000000..550860c9 --- /dev/null +++ b/src/commands/debug/parser.rs @@ -0,0 +1,89 @@ +use nom::branch::alt; +use nom::bytes::complete::{tag, take_while}; +use nom::character::complete::{alpha1, char, space1, u32, u64}; +use nom::combinator::{all_consuming, value}; +use nom::sequence::tuple; +use nom::IResult; + +use bch_bindgen::c::bpos; + +use crate::commands::debug::{DebugCommand, DumpCommand, UpdateCommand}; + +fn parse_bpos(input: &str) -> IResult<&str, bpos> { + let (input, (inode, _, offset, _, snapshot)) = tuple(( + u64, + char(':'), + u64, + char(':'), + alt((u32, value(u32::MAX, tag("U32_MAX")))), + ))(input)?; + + Ok(( + input, + bpos { + inode, + offset, + snapshot, + }, + )) +} + +fn parse_dump_cmd(input: &str) -> IResult<&str, DebugCommand> { + let (input, (_, btree, _, bpos)) = + all_consuming(tuple((space1, alpha1, space1, parse_bpos)))(input)?; + + Ok(( + input, + DebugCommand::Dump(DumpCommand { + btree: btree.to_string(), + bpos, + }), + )) +} + +fn symbol_name(input: &str) -> IResult<&str, &str> { + take_while(|c: char| c.is_alphabetic() || c == '_')(input) +} + +fn parse_update_cmd(input: &str) -> IResult<&str, DebugCommand> { + let (input, (_, btree, _, bpos, _, bkey, _, field, _, value)) = all_consuming(tuple(( + space1, + alpha1, + space1, + parse_bpos, + space1, + symbol_name, + char('.'), + symbol_name, + char('='), + u64, + )))(input)?; + + Ok(( + input, + DebugCommand::Update(UpdateCommand { + btree: btree.to_string(), + bpos, + bkey: bkey.to_string(), + field: field.to_string(), + value, + }), + )) +} + +fn parse_command_inner(input: &str) -> IResult<&str, DebugCommand> { + let (input, cmd) = alt((tag("dump"), tag("update")))(input)?; + + match cmd { + "dump" => parse_dump_cmd(input), + "update" => parse_update_cmd(input), + _ => unreachable!(), + } +} + +pub fn parse_command(input: &str) -> Option<DebugCommand> { + match parse_command_inner(input) { + Ok((_, c)) => Some(c), + Err(_) => None, + } +} |