summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2019-12-21 23:00:52 +0000
committerNadrieril2019-12-21 23:00:52 +0000
commitbe9510bc21724077fd27dcdb3825557475a6bb44 (patch)
tree150b015ee7242a14fc064b65956a0c98c73706b1 /dhall
parenta588b946ecc9881090ae52e1a1cf81f4607f3426 (diff)
Generate parser manually to make the crate publishable
Diffstat (limited to '')
-rw-r--r--dhall/.gitignore1
-rw-r--r--dhall/Cargo.toml2
-rw-r--r--dhall/build.rs28
-rw-r--r--dhall/src/syntax/text/parser.rs12
4 files changed, 37 insertions, 6 deletions
diff --git a/dhall/.gitignore b/dhall/.gitignore
deleted file mode 100644
index 8a0bac6..0000000
--- a/dhall/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-src/dhall.pest
diff --git a/dhall/Cargo.toml b/dhall/Cargo.toml
index 44c8932..a9c237c 100644
--- a/dhall/Cargo.toml
+++ b/dhall/Cargo.toml
@@ -27,5 +27,7 @@ pretty_assertions = "0.6.1"
[build-dependencies]
walkdir = "2"
abnf_to_pest = { version = "0.1.2", path = "../abnf_to_pest" }
+pest_generator = "2.1"
+quote = "1.0"
diff --git a/dhall/build.rs b/dhall/build.rs
index 50f423e..3021f03 100644
--- a/dhall/build.rs
+++ b/dhall/build.rs
@@ -408,9 +408,10 @@ fn generate_tests() -> std::io::Result<()> {
}
fn convert_abnf_to_pest() -> std::io::Result<()> {
+ let out_dir = env::var("OUT_DIR").unwrap();
let abnf_path = "src/dhall.abnf";
let visibility_path = "src/dhall.pest.visibility";
- let pest_path = "src/dhall.pest";
+ let grammar_path = Path::new(&out_dir).join("dhall.pest");
println!("cargo:rerun-if-changed={}", abnf_path);
println!("cargo:rerun-if-changed={}", visibility_path);
@@ -427,7 +428,7 @@ fn convert_abnf_to_pest() -> std::io::Result<()> {
}
}
- let mut file = File::create(pest_path)?;
+ let mut file = File::create(grammar_path)?;
writeln!(&mut file, "// AUTO-GENERATED FILE. See build.rs.")?;
// TODO: this is a cheat; properly support RFC3986 URLs instead
@@ -493,8 +494,31 @@ fn convert_abnf_to_pest() -> std::io::Result<()> {
Ok(())
}
+// Generate pest parser manually becaue otherwise we'd need to modify something outside of
+// OUT_DIR and that's forbidden by docs.rs.
+fn generate_pest_parser() -> std::io::Result<()> {
+ let out_dir = env::var("OUT_DIR").unwrap();
+ let grammar_path = Path::new(&out_dir).join("dhall.pest");
+ let grammar_path = grammar_path.to_str();
+ let output_path = Path::new(&out_dir).join("dhall_parser.rs");
+
+ let pest = quote::quote!(
+ #[grammar = #grammar_path]
+ struct DhallParser;
+ );
+ let derived = pest_generator::derive_parser(pest, false);
+ let file_contents = quote::quote!(
+ struct DhallParser;
+ #derived
+ );
+
+ let mut file = File::create(output_path)?;
+ writeln!(file, "{}", file_contents)
+}
+
fn main() -> std::io::Result<()> {
convert_abnf_to_pest()?;
+ generate_pest_parser()?;
generate_tests()?;
Ok(())
}
diff --git a/dhall/src/syntax/text/parser.rs b/dhall/src/syntax/text/parser.rs
index 90cb4b1..832472b 100644
--- a/dhall/src/syntax/text/parser.rs
+++ b/dhall/src/syntax/text/parser.rs
@@ -156,9 +156,15 @@ lazy_static::lazy_static! {
};
}
-#[derive(Parser)]
-#[grammar = "dhall.pest"]
-struct DhallParser;
+// Generate pest parser manually becaue otherwise we'd need to modify something outside of OUT_DIR
+// and that's forbidden by docs.rs.
+// This is equivalent to:
+// ```
+// #[derive(Parser)
+// #[grammar = "..."]
+// struct DhallParser;
+// ```
+include!(concat!(env!("OUT_DIR"), "/dhall_parser.rs"));
#[pest_consume::parser(parser = DhallParser, rule = Rule)]
impl DhallParser {