refactor(parsing): remove old FromStr-based parser implementation
This commit is contained in:
parent
106c2547b5
commit
6b49d3ca14
9 changed files with 67 additions and 99 deletions
|
|
@ -187,8 +187,11 @@ CLOCK: [2025-05-04 dim. 14:01]--[2025-05-04 dim. 14:14] => 0:13
|
|||
|
||||
* DONE error offsets are incorrect
|
||||
|
||||
* TODO remove old FromStr parser implementation
|
||||
* DONE remove old FromStr parser implementation
|
||||
|
||||
* TODO use a better readline impl
|
||||
|
||||
* TODO handle non-interactive input better
|
||||
|
||||
* TODO cli tests using insta-cmd
|
||||
https://insta.rs/docs/cmd/
|
||||
|
|
|
|||
|
|
@ -94,25 +94,11 @@ impl From<ScanError> for CommandParseError {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Command {
|
||||
type Err = CommandParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s.starts_with(".") {
|
||||
s.parse::<MetaCommand>()
|
||||
.map(|x| x.into())
|
||||
.map_err(|x| x.into())
|
||||
} else {
|
||||
s.parse::<Statement>()
|
||||
.map(|x| x.into())
|
||||
.map_err(|x| x.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{command::Command, meta_commands::MetaCommand, statements::Statement};
|
||||
use crate::{
|
||||
command::Command, meta_commands::MetaCommand, parser::parse, statements::Statement,
|
||||
};
|
||||
use insta::{assert_debug_snapshot, assert_snapshot};
|
||||
|
||||
#[test]
|
||||
|
|
@ -136,11 +122,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_parse_wrong_statement() {
|
||||
assert_debug_snapshot!("salact".parse::<Command>());
|
||||
assert_debug_snapshot!(parse("<stdin>".to_string(), "salact".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_wrong_meta_command() {
|
||||
assert_debug_snapshot!(".halp".parse::<Command>());
|
||||
assert_debug_snapshot!(parse("<stdin>".to_string(), ".halp".to_string()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,16 +29,3 @@ impl std::fmt::Display for MetaCommandParseError {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for MetaCommand {
|
||||
type Err = MetaCommandParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.trim() {
|
||||
".exit" => Ok(MetaCommand::Exit),
|
||||
cmd => Err(MetaCommandParseError::Unrecognized {
|
||||
cmd: cmd.to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
---
|
||||
source: src/command.rs
|
||||
expression: "\".halp\".parse::<Command>()"
|
||||
expression: "parse(\"<stdin>\".to_string(), \".halp\".to_string())"
|
||||
---
|
||||
Err(
|
||||
MetaCommand(
|
||||
Unrecognized {
|
||||
cmd: ".halp",
|
||||
},
|
||||
),
|
||||
[
|
||||
Scan(
|
||||
ScanError {
|
||||
location: Location {
|
||||
file: "<stdin>",
|
||||
offset: 0,
|
||||
length: 5,
|
||||
},
|
||||
kind: UnknownMetaCommand(
|
||||
".halp",
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
---
|
||||
source: src/command.rs
|
||||
expression: "\"salact\".parse::<Command>()"
|
||||
expression: "parse(\"<stdin>\".to_string(), \"salact\".to_string())"
|
||||
---
|
||||
Err(
|
||||
Statement(
|
||||
Unrecognized {
|
||||
stmt: "salact",
|
||||
},
|
||||
),
|
||||
[
|
||||
Scan(
|
||||
ScanError {
|
||||
location: Location {
|
||||
file: "<stdin>",
|
||||
offset: 0,
|
||||
length: 6,
|
||||
},
|
||||
kind: UnknownKeyword(
|
||||
"salact",
|
||||
),
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
---
|
||||
source: src/parser.rs
|
||||
expression: "parse(file, String::from(\".exit\"))"
|
||||
---
|
||||
Ok(
|
||||
[
|
||||
MetaCommand(
|
||||
Exit,
|
||||
),
|
||||
],
|
||||
)
|
||||
26
src/snapshots/osdb__tokens__tests__tokenizer_errors.snap
Normal file
26
src/snapshots/osdb__tokens__tests__tokenizer_errors.snap
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
source: src/tokens.rs
|
||||
expression: scanerrors
|
||||
---
|
||||
[
|
||||
ScanError {
|
||||
location: Location {
|
||||
file: "src/statement.sql",
|
||||
offset: 0,
|
||||
length: 6,
|
||||
},
|
||||
kind: UnknownKeyword(
|
||||
"salact",
|
||||
),
|
||||
},
|
||||
ScanError {
|
||||
location: Location {
|
||||
file: "src/statement.sql",
|
||||
offset: 7,
|
||||
length: 1,
|
||||
},
|
||||
kind: UnexpectedChar(
|
||||
'+',
|
||||
),
|
||||
},
|
||||
]
|
||||
|
|
@ -19,24 +19,6 @@ impl std::fmt::Display for StatementParseError {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Statement {
|
||||
type Err = StatementParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let s = s.trim();
|
||||
let lower = s.to_lowercase();
|
||||
if lower.starts_with("insert") {
|
||||
Ok(Statement::Insert)
|
||||
} else if lower.starts_with("select") {
|
||||
Ok(Statement::Select)
|
||||
} else {
|
||||
Err(StatementParseError::Unrecognized {
|
||||
stmt: s.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StatementExecuteResult {
|
||||
pub msg: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -307,32 +307,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_tokenizer_errors() {
|
||||
let mut scanerrors = tokenize("salact +".to_string(), "src/statement.sql".to_string())
|
||||
let scanerrors = tokenize("salact +".to_string(), "src/statement.sql".to_string())
|
||||
.err()
|
||||
.unwrap();
|
||||
scanerrors.reverse();
|
||||
assert_eq!(
|
||||
scanerrors.pop(),
|
||||
Some(ScanError {
|
||||
location: Location {
|
||||
file: "src/statement.sql".to_string(),
|
||||
offset: 0,
|
||||
length: 6,
|
||||
},
|
||||
kind: ScanErrorKind::UnknownKeyword("salact".to_string()),
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
scanerrors.pop(),
|
||||
Some(ScanError {
|
||||
location: Location {
|
||||
file: "src/statement.sql".to_string(),
|
||||
offset: 8,
|
||||
length: 1,
|
||||
},
|
||||
kind: ScanErrorKind::UnexpectedChar('+'),
|
||||
})
|
||||
);
|
||||
assert!(scanerrors.is_empty());
|
||||
assert_debug_snapshot!(scanerrors);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue