Skip to content

Commit

Permalink
Use the source-relative path in include_str!
Browse files Browse the repository at this point in the history
Pest needs the full path with CARGO_MANIFEST_DIR to read the grammar
file, but when emitting `include_str!` the original path (relative to
the Rust source file) should be used.
  • Loading branch information
tmandry committed Jun 30, 2021
1 parent b2c3508 commit 723d006
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 20 deletions.
20 changes: 5 additions & 15 deletions generator/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use std::path::PathBuf;

use proc_macro2::{Span, TokenStream};
use quote::{ToTokens, TokenStreamExt};
use syn::{self, Generics, Ident};
Expand All @@ -21,7 +19,7 @@ use pest_meta::UNICODE_PROPERTY_NAMES;
pub fn generate(
name: Ident,
generics: &Generics,
path: Option<PathBuf>,
path: Option<String>,
rules: Vec<OptimizedRule>,
defaults: Vec<&str>,
include_grammar: bool,
Expand All @@ -31,7 +29,7 @@ pub fn generate(
let builtins = generate_builtin_rules();
let include_fix = if include_grammar {
match path {
Some(ref path) => generate_include(&name, path.to_str().expect("non-Unicode path")),
Some(ref path) => generate_include(&name, path),
None => quote!(),
}
} else {
Expand Down Expand Up @@ -167,14 +165,9 @@ fn generate_builtin_rules() -> Vec<(&'static str, TokenStream)> {
// Needed because Cargo doesn't watch for changes in grammars.
fn generate_include(name: &Ident, path: &str) -> TokenStream {
let const_name = Ident::new(&format!("_PEST_GRAMMAR_{}", name), Span::call_site());
// Need to make this relative to the current directory since the path to the file
// is derived from the CARGO_MANIFEST_DIR environment variable
let mut current_dir = std::env::current_dir().expect("Unable to get current directory");
current_dir.push(path);
let relative_path = current_dir.to_str().expect("path contains invalid unicode");
quote! {
#[allow(non_upper_case_globals)]
const #const_name: &'static str = include_str!(#relative_path);
const #const_name: &'static str = include_str!(#path);
}
}

Expand Down Expand Up @@ -936,14 +929,11 @@ mod tests {
expr: OptimizedExpr::Str("b".to_owned()),
}];
let defaults = vec!["ANY"];
let mut current_dir = std::env::current_dir().expect("Unable to get current directory");
current_dir.push("test.pest");
let test_path = current_dir.to_str().expect("path contains invalid unicode");
assert_eq!(
generate(name, &generics, Some(PathBuf::from("test.pest")), rules, defaults, true).to_string(),
generate(name, &generics, Some(String::from("test.pest")), rules, defaults, true).to_string(),
quote! {
#[allow(non_upper_case_globals)]
const _PEST_GRAMMAR_MyParser: &'static str = include_str!(#test_path);
const _PEST_GRAMMAR_MyParser: &'static str = include_str!("test.pest");

#[allow(dead_code, non_camel_case_types, clippy::upper_case_acronyms)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
Expand Down
10 changes: 5 additions & 5 deletions generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,19 @@ pub fn derive_parser(input: TokenStream, include_grammar: bool) -> TokenStream {
let (name, generics, content) = parse_derive(ast);

let (data, path) = match content {
GrammarSource::File(ref path) => {
GrammarSource::File(path) => {
let root = env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into());
let path = Path::new(&root).join("src/").join(&path);
let file_name = match path.file_name() {
let full_path = Path::new(&root).join("src/").join(&path);
let file_name = match full_path.file_name() {
Some(file_name) => file_name,
None => panic!("grammar attribute should point to a file"),
};

let data = match read_file(&path) {
let data = match read_file(&full_path) {
Ok(data) => data,
Err(error) => panic!("error opening {:?}: {}", file_name, error),
};
(data, Some(path.clone()))
(data, Some(path))
}
GrammarSource::Inline(content) => (content, None),
};
Expand Down

0 comments on commit 723d006

Please sign in to comment.