-use std::collections::HashMap;
+use std::{collections::HashMap, path::PathBuf};
#[derive(Debug, Default, Clone)]
pub struct MetaFile<'a> {
source: Vec::new(),
}
}
+
+ pub fn get_var(&self, key: &str) -> Option<&str> {
+ self.variables.get(key).copied()
+ }
+
+ pub fn get_arr(&self, key: &str) -> Option<&[&str]> {
+ self.arrays.get(key).map(|val| &val[..])
+ }
+
+ pub fn get_pat(&self, key: &str) -> Option<&str> {
+ self.patterns.get(key).copied()
+ }
}
+#[macro_export]
+macro_rules! source (
+ (var($s:expr)) => { Source::Sub(Substitution::Variable($s))};
+ (arr($s:expr)) => { Source::Sub(Substitution::Array($s))};
+ (pat($s:expr)) => { Source::Sub(Substitution::Pattern($s))};
+ ($s:expr) => { Source::Str($s)};
+);
+
#[derive(Debug, Clone, PartialEq)]
pub enum Source<'a> {
Str(&'a str),
Array(&'a str),
Pattern(&'a str),
}
+
+#[derive(Debug, Clone)]
+pub struct RootDirs {
+ pub source: PathBuf,
+ pub build: PathBuf,
+ pub pattern: PathBuf,
+}
-use crate::{MetaFile, Source, Substitution};
+use crate::{source, MetaFile, Source, Substitution};
use color_eyre::Result;
use pest::{
iterators::{Pair, Pairs},
map
}
-fn parse_array_defs(pairs: Pairs<Rule>) -> HashMap<&'_ str, Vec<&'_ str>> {
+fn parse_array_defs(pairs: Pairs<Rule>) -> HashMap<&str, Vec<&str>> {
let mut map = HashMap::new();
for pair in pairs {
if Rule::assign == pair.as_rule() {
}
fn parse_source(pairs: Pairs<Rule>) -> Vec<Source> {
- let mut vec: Vec<Source> = Vec::new();
-
- macro_rules! push_src (
- (var($s:expr)) => { vec.push(Source::Sub(Substitution::Variable($s))) };
- (arr($s:expr)) => { vec.push(Source::Sub(Substitution::Array($s))) };
- (pat($s:expr)) => { vec.push(Source::Sub(Substitution::Pattern($s))) };
- ($s:expr) => { vec.push(Source::Str($s)) };
- );
-
+ let mut vec = Vec::new();
for pair in pairs {
match pair.as_rule() {
- Rule::var_sub => push_src!(var(parse_substitution(pair))),
- Rule::arr_sub => push_src!(arr(parse_substitution(pair))),
- Rule::pat_sub => push_src!(pat(parse_substitution(pair))),
- Rule::char_seq => push_src!(pair.as_str()),
+ Rule::var_sub => vec.push(source!(var(parse_sub(pair)))),
+ Rule::arr_sub => vec.push(source!(arr(parse_sub(pair)))),
+ Rule::pat_sub => vec.push(source!(pat(parse_sub(pair)))),
+ Rule::char_seq => vec.push(source!(pair.as_str())),
// anything that isn't a substitution is a char_seq inside source
_ => unreachable!(),
}
vec
}
-fn parse_substitution(pair: Pair<Rule>) -> &'_ str {
+fn parse_sub(pair: Pair<Rule>) -> &'_ str {
match pair.as_rule() {
Rule::var_sub | Rule::arr_sub | Rule::pat_sub => {
let str = pair.as_str();
// return the value as the inner string for substitution
// all substitutions have the format of
// *{ ... }
- // we return everything except the first
- // two characters: (sigil and preceding brace)
- // and the trailing brace
+ // we return everything except:
+ // first two characters: (sigil and preceding brace)
+ // and the trailing brace
&str[2..str.len() - 1]
}
// this function only gets called to parse substituiton patterns
+ // so anything else should never be called
_ => unreachable!(),
}
}
if tmp == "BLANK" || tmp == "DEFAULT" {
return ("", "");
}
- // remove surrounding quotes from values
+ // remove surrounding quotes from values by returning
+ // everything except first and last characters
+ // a string is defined as " ... " or ' ... '
+ // so it's safe to strip these characters
val = &tmp[1..tmp.len() - 1];
}
}
(key, val)
}
-fn parse_assign_array(pair: Pair<Rule>) -> (&'_ str, Vec<&'_ str>) {
+fn parse_assign_array(pair: Pair<Rule>) -> (&str, Vec<&str>) {
let mut key = "";
- let mut val: Vec<&str> = Vec::default();
+ let mut val = Vec::default();
for pair in pair.into_inner() {
if Rule::key == pair.as_rule() {
key = pair.as_str();
(key, val)
}
-fn parse_array(pairs: Pairs<Rule>) -> Vec<&'_ str> {
+fn parse_array(pairs: Pairs<Rule>) -> Vec<&str> {
let mut vec: Vec<&str> = Vec::default();
for pair in pairs {
--- /dev/null
+use crate::parse_file;
+use color_eyre::Result;
+
+static SOURCE: &str = include_str!("test_source.meta");
+
+#[test]
+fn test_metafile_gets() -> Result<()> {
+ let source = parse_file(SOURCE)?;
+
+ assert_eq!(source.get_var("var").unwrap(), "good");
+ assert_eq!(source.get_var("single").unwrap(), "quotes");
+ assert_eq!(source.get_var("blank"), None);
+ assert_eq!(source.get_var("not_defined"), None);
+
+ assert_eq!(source.get_arr("sub.array").unwrap(), ["sub", "value"]);
+ assert_eq!(source.get_arr("arr").unwrap(), ["split", "up", "values"]);
+ assert_eq!(
+ source.get_arr("with_spaces").unwrap(),
+ ["stuff", "with", "spaces"]
+ );
+ assert_eq!(source.get_arr("not_defined"), None);
+
+ assert_eq!(source.get_pat("pat").unwrap(), "pattern");
+ assert_eq!(source.get_pat("pat.sub_pat"), None);
+ assert_eq!(source.get_pat("blank_pat"), None);
+ assert_eq!(source.get_pat("not_defined"), None);
+
+ Ok(())
+}