Return error instead of panic on failed parse
This commit is contained in:
23
Cargo.lock
generated
23
Cargo.lock
generated
@ -46,10 +46,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blueprint"
|
name = "blueprint"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nom",
|
"nom",
|
||||||
"structopt",
|
"structopt",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -257,6 +258,26 @@ dependencies = [
|
|||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.7.1"
|
version = "1.7.1"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "blueprint"
|
name = "blueprint"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
authors = ["Joakim Hulthe <joakim@hulthe.net>"]
|
authors = ["Joakim Hulthe <joakim@hulthe.net>"]
|
||||||
description = "A simple templating library"
|
description = "A simple templating library"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
@ -9,3 +9,4 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
nom = "6.1.2"
|
nom = "6.1.2"
|
||||||
structopt = "0.3.21"
|
structopt = "0.3.21"
|
||||||
|
thiserror = "1.0.24"
|
||||||
|
|||||||
7
src/error.rs
Normal file
7
src/error.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Failed to parse template")]
|
||||||
|
ParseError,
|
||||||
|
}
|
||||||
18
src/lib.rs
18
src/lib.rs
@ -1,10 +1,12 @@
|
|||||||
mod ast;
|
mod ast;
|
||||||
mod env;
|
mod env;
|
||||||
|
mod error;
|
||||||
mod parser;
|
mod parser;
|
||||||
|
|
||||||
pub use ast::{CmpOp, Expr, IfThen, Part, Template};
|
pub use ast::{CmpOp, Expr, IfThen, Part, Template};
|
||||||
pub use env::{Env, Value};
|
pub use env::{Env, Value};
|
||||||
pub use parser::parse_file;
|
pub use error::Error;
|
||||||
|
pub use parser::parse_template;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
@ -13,7 +15,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_empty() {
|
fn test_parse_empty() {
|
||||||
let input = "";
|
let input = "";
|
||||||
let ast = parse_file(&input).expect("failed to parse");
|
let ast = parse_template(&input).expect("failed to parse");
|
||||||
eprintln!("{:#?}", ast);
|
eprintln!("{:#?}", ast);
|
||||||
assert_eq!(ast, Template { parts: vec![] });
|
assert_eq!(ast, Template { parts: vec![] });
|
||||||
}
|
}
|
||||||
@ -21,7 +23,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_text() {
|
fn test_parse_text() {
|
||||||
let input = "hello there GENERAL KENOBI";
|
let input = "hello there GENERAL KENOBI";
|
||||||
let ast = parse_file(&input).expect("failed to parse");
|
let ast = parse_template(&input).expect("failed to parse");
|
||||||
eprintln!("{:#?}", ast);
|
eprintln!("{:#?}", ast);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ast,
|
ast,
|
||||||
@ -34,7 +36,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_if() {
|
fn test_parse_if() {
|
||||||
let input = "one {% if foo %} two {% end %} three";
|
let input = "one {% if foo %} two {% end %} three";
|
||||||
let ast = parse_file(&input).expect("failed to parse");
|
let ast = parse_template(&input).expect("failed to parse");
|
||||||
eprintln!("{:#?}", ast);
|
eprintln!("{:#?}", ast);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ast,
|
ast,
|
||||||
@ -58,7 +60,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_if_str() {
|
fn test_parse_if_str() {
|
||||||
let input = "one {% if foo >= \"bar\" %} two {% end %} three";
|
let input = "one {% if foo >= \"bar\" %} two {% end %} three";
|
||||||
let ast = parse_file(&input).expect("failed to parse");
|
let ast = parse_template(&input).expect("failed to parse");
|
||||||
eprintln!("{:#?}", ast);
|
eprintln!("{:#?}", ast);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ast,
|
ast,
|
||||||
@ -86,7 +88,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_eq() {
|
fn test_parse_eq() {
|
||||||
let input = "one {% if foo == bar %} two {% end %} three";
|
let input = "one {% if foo == bar %} two {% end %} three";
|
||||||
let ast = parse_file(&input).expect("failed to parse");
|
let ast = parse_template(&input).expect("failed to parse");
|
||||||
eprintln!("{:#?}", ast);
|
eprintln!("{:#?}", ast);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ast,
|
ast,
|
||||||
@ -114,7 +116,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_if_elif_else() {
|
fn test_parse_if_elif_else() {
|
||||||
let input = "one {% if foo %} two {% elif bar %} three {% else %} four {% end %} five";
|
let input = "one {% if foo %} two {% elif bar %} three {% else %} four {% end %} five";
|
||||||
let ast = parse_file(&input).expect("failed to parse");
|
let ast = parse_template(&input).expect("failed to parse");
|
||||||
eprintln!("{:#?}", ast);
|
eprintln!("{:#?}", ast);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ast,
|
ast,
|
||||||
@ -141,7 +143,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_nested() {
|
fn test_parse_nested() {
|
||||||
let input = "one {% if foo %} two {% if bar %} three {% end %} four {% end %} five";
|
let input = "one {% if foo %} two {% if bar %} three {% end %} four {% end %} five";
|
||||||
let ast = parse_file(&input).expect("failed to parse");
|
let ast = parse_template(&input).expect("failed to parse");
|
||||||
eprintln!("{:#?}", ast);
|
eprintln!("{:#?}", ast);
|
||||||
let expected = Template {
|
let expected = Template {
|
||||||
parts: vec![
|
parts: vec![
|
||||||
|
|||||||
@ -13,11 +13,11 @@ struct Opt {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let opt = Opt::from_args();
|
let opt = Opt::from_args();
|
||||||
let file = read_to_string(&opt.template).expect("failed to load file");
|
let file = read_to_string(&opt.template).expect("failed to load file");
|
||||||
let template = blueprint::parse_file(&file).expect("failed to parse");
|
let template = blueprint::parse_template(&file).expect("failed to parse");
|
||||||
let env = opt
|
let env = opt
|
||||||
.env
|
.env
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|key| (key, Value::Str("".into())))
|
.map(|key| (key, Value::Bool(true)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut stdout = io::stdout();
|
let mut stdout = io::stdout();
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::ast::*;
|
use crate::ast::{CmpOp, Expr, IfThen, Part, Template};
|
||||||
|
use crate::Error;
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::{is_not, tag, take_until},
|
bytes::complete::{is_not, tag, take_until},
|
||||||
@ -162,19 +163,21 @@ fn block(word: &'static str) -> impl Fn(&str) -> IResult<&str, ()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_file(file: &str) -> Result<Template, ()> {
|
pub fn parse_template(template: &str) -> Result<Template, Error> {
|
||||||
match parts(file) {
|
match parts(template) {
|
||||||
Ok((rest, parts)) => {
|
Ok((rest, parts)) => {
|
||||||
//eprintln!("{:#?}", parts);
|
//eprintln!("{:#?}", parts);
|
||||||
|
|
||||||
if rest != "" {
|
if rest != "" {
|
||||||
panic!("failed to parse input. remainder: \"{}\"", rest);
|
//panic!("failed to parse input. remainder: \"{}\"", rest);
|
||||||
|
Err(Error::ParseError)
|
||||||
|
} else {
|
||||||
|
Ok(Template { parts })
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Template { parts })
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(_e) => {
|
||||||
panic!("{:#?}", e);
|
//panic!("{:#?}", _e);
|
||||||
|
Err(Error::ParseError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user