mirror of
https://github.com/zaphar/sheetsui.git
synced 2025-07-23 13:29:48 -04:00
100 lines
3.1 KiB
Rust
100 lines
3.1 KiB
Rust
|
//! Command mode command parsers.
|
||
|
use slice_cursor::{Cursor, Seekable, Span, SpanRange, StrCursor};
|
||
|
|
||
|
#[derive(Debug, PartialEq, Eq)]
|
||
|
pub enum Cmd<'a> {
|
||
|
Write(Option<&'a str>),
|
||
|
InsertRow(usize),
|
||
|
InsertColumns(usize),
|
||
|
Edit(&'a str),
|
||
|
Help(Option<&'a str>),
|
||
|
}
|
||
|
|
||
|
pub fn parse<'cmd, 'i: 'cmd>(input: &'i str) -> Result<Option<Cmd<'cmd>>, &'static str> {
|
||
|
let cursor = StrCursor::new(input);
|
||
|
// try consume write command.
|
||
|
if let Some(cmd) = try_consume_write(cursor.clone()) {
|
||
|
return Ok(Some(cmd));
|
||
|
}
|
||
|
// try consume insert-row command.
|
||
|
if let Some(cmd) = try_consume_insert_row(cursor.clone())? {
|
||
|
return Ok(Some(cmd));
|
||
|
}
|
||
|
// try consume insert-col command.
|
||
|
if let Some(cmd) = try_consume_insert_column(cursor.clone()) {
|
||
|
return Ok(Some(cmd));
|
||
|
}
|
||
|
// try consume edit command.
|
||
|
if let Some(cmd) = try_consume_edit(cursor.clone()) {
|
||
|
return Ok(Some(cmd));
|
||
|
}
|
||
|
// try consume help command.
|
||
|
if let Some(cmd) = try_consume_help(cursor.clone()) {
|
||
|
return Ok(Some(cmd));
|
||
|
}
|
||
|
Ok(None)
|
||
|
}
|
||
|
|
||
|
const WRITE: &'static str = "write";
|
||
|
|
||
|
pub fn try_consume_write<'cmd, 'i: 'cmd>(mut input: StrCursor<'i>) -> Option<Cmd<'cmd>> {
|
||
|
let prefix_len = WRITE.len();
|
||
|
let full_length = dbg!(input.span(..).len());
|
||
|
let arg = if full_length >= prefix_len && input.span(..prefix_len) == WRITE {
|
||
|
input.seek(prefix_len);
|
||
|
// Should we check for whitespace?
|
||
|
input.span(prefix_len..)
|
||
|
} else if full_length >= 2 && input.span(..2) == "w " {
|
||
|
input.span(2..)
|
||
|
// Should we check for whitespace?
|
||
|
} else {
|
||
|
return None;
|
||
|
}
|
||
|
.trim();
|
||
|
return Some(Cmd::Write(if arg.is_empty() { None } else { Some(arg) }));
|
||
|
}
|
||
|
|
||
|
const IR: &'static str = "ir";
|
||
|
const INSERT_ROW: &'static str = "insert-row";
|
||
|
|
||
|
pub fn try_consume_insert_row<'cmd, 'i: 'cmd>(
|
||
|
mut input: StrCursor<'i>,
|
||
|
) -> Result<Option<Cmd<'cmd>>, &'static str> {
|
||
|
let prefix_len = INSERT_ROW.len();
|
||
|
let second_prefix_len = IR.len();
|
||
|
let full_length = input.span(..).len();
|
||
|
let arg =
|
||
|
if full_length >= prefix_len && input.span(..prefix_len) == INSERT_ROW {
|
||
|
input.seek(prefix_len);
|
||
|
// Should we check for whitespace?
|
||
|
input.span(prefix_len..)
|
||
|
} else if full_length >= second_prefix_len && input.span(..second_prefix_len) == IR {
|
||
|
input.span(second_prefix_len..)
|
||
|
// Should we check for whitespace?
|
||
|
} else {
|
||
|
return Ok(None);
|
||
|
}
|
||
|
.trim();
|
||
|
return Ok(Some(Cmd::InsertRow(if arg.is_empty() {
|
||
|
1
|
||
|
} else {
|
||
|
if let Ok(count) = arg.parse() {
|
||
|
count
|
||
|
} else {
|
||
|
return Err("You must pass in a non negative number for the row count");
|
||
|
}
|
||
|
})));
|
||
|
}
|
||
|
|
||
|
pub fn try_consume_insert_column<'cmd, 'i: 'cmd>(mut input: StrCursor<'i>) -> Option<Cmd<'cmd>> {
|
||
|
todo!("insert-column not yet implemented")
|
||
|
}
|
||
|
|
||
|
pub fn try_consume_edit<'cmd, 'i: 'cmd>(mut input: StrCursor<'i>) -> Option<Cmd<'cmd>> {
|
||
|
todo!("edit not yet implemented")
|
||
|
}
|
||
|
|
||
|
pub fn try_consume_help<'cmd, 'i: 'cmd>(mut input: StrCursor<'i>) -> Option<Cmd<'cmd>> {
|
||
|
todo!("help not yet implemented")
|
||
|
}
|