summaryrefslogtreecommitdiff
path: root/src/commands/debug/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/debug/parser.rs')
-rw-r--r--src/commands/debug/parser.rs89
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,
+ }
+}