preset: initial work on context
This commit is contained in:
parent
6d4e6590de
commit
f1524f6049
2 changed files with 30 additions and 8 deletions
|
@ -1,3 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
use nom_locate::LocatedSpan;
|
||||
|
@ -22,7 +23,12 @@ pub(crate) fn remove_if<T>(values: &mut Vec<T>, f: impl FnMut(&T) -> bool) -> Op
|
|||
impl ShaderPreset {
|
||||
/// Try to parse the shader preset at the given path.
|
||||
pub fn try_parse(path: impl AsRef<Path>) -> Result<ShaderPreset, ParsePresetError> {
|
||||
let values = parse_preset(path)?;
|
||||
ShaderPreset::try_parse_with_context(path, HashMap::new())
|
||||
}
|
||||
|
||||
/// Try to parse the shader preset at the given path.
|
||||
pub fn try_parse_with_context(path: impl AsRef<Path>, context: HashMap<String, String>) -> Result<ShaderPreset, ParsePresetError> {
|
||||
let values = parse_preset(path, context)?;
|
||||
Ok(resolve_values(values))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::{ScaleFactor, ScaleType};
|
|||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::digit1;
|
||||
use nom::combinator::{eof, map_res};
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
|
||||
use nom::IResult;
|
||||
use num_traits::cast::ToPrimitive;
|
||||
|
@ -150,9 +150,11 @@ fn parse_indexed_key<'a>(key: &'static str, input: Span<'a>) -> IResult<Span<'a>
|
|||
|
||||
pub const SHADER_MAX_REFERENCE_DEPTH: usize = 16;
|
||||
|
||||
// prereq: root_path must be contextualized
|
||||
fn load_child_reference_strings(
|
||||
root_references: Vec<PathBuf>,
|
||||
root_path: impl AsRef<Path>,
|
||||
context: &HashMap<String, String>
|
||||
) -> Result<Vec<(PathBuf, String)>, ParsePresetError> {
|
||||
let root_path = root_path.as_ref();
|
||||
|
||||
|
@ -161,13 +163,14 @@ fn load_child_reference_strings(
|
|||
let root_references = vec![(root_path.to_path_buf(), root_references)];
|
||||
let mut root_references = VecDeque::from(root_references);
|
||||
// search needs to be depth first to allow for overrides.
|
||||
while let Some((reference_root, referenced_paths)) = root_references.pop_front() {
|
||||
while let Some((mut reference_root, referenced_paths)) = root_references.pop_front() {
|
||||
if reference_depth > SHADER_MAX_REFERENCE_DEPTH {
|
||||
return Err(ParsePresetError::ExceededReferenceDepth);
|
||||
}
|
||||
// enter the current root
|
||||
reference_depth += 1;
|
||||
// canonicalize current root
|
||||
apply_context(&mut reference_root, context);
|
||||
let reference_root = reference_root
|
||||
.canonicalize()
|
||||
.map_err(|e| ParsePresetError::IOError(reference_root.to_path_buf(), e))?;
|
||||
|
@ -177,8 +180,10 @@ fn load_child_reference_strings(
|
|||
|
||||
for path in referenced_paths {
|
||||
let mut path = reference_root
|
||||
.join(path.clone())
|
||||
.canonicalize()
|
||||
.join(path.clone());
|
||||
apply_context(&mut path, context);
|
||||
|
||||
let mut path = path.canonicalize()
|
||||
.map_err(|e| ParsePresetError::IOError(path.clone(), e))?;
|
||||
// println!("Opening {:?}", path);
|
||||
let mut reference_contents = String::new();
|
||||
|
@ -204,8 +209,15 @@ fn load_child_reference_strings(
|
|||
Ok(reference_strings.into())
|
||||
}
|
||||
|
||||
pub fn parse_preset(path: impl AsRef<Path>) -> Result<Vec<Value>, ParsePresetError> {
|
||||
fn apply_context(path: &mut PathBuf, context: &HashMap<String, String>) {
|
||||
|
||||
}
|
||||
|
||||
pub fn parse_preset(path: impl AsRef<Path>, context: HashMap<String, String>) -> Result<Vec<Value>, ParsePresetError> {
|
||||
let path = path.as_ref();
|
||||
let mut path = path.to_path_buf();
|
||||
apply_context(&mut path, &context);
|
||||
|
||||
let path = path
|
||||
.canonicalize()
|
||||
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
|
||||
|
@ -216,12 +228,14 @@ pub fn parse_preset(path: impl AsRef<Path>) -> Result<Vec<Value>, ParsePresetErr
|
|||
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
|
||||
|
||||
let tokens = super::token::do_lex(&contents)?;
|
||||
parse_values(tokens, path)
|
||||
parse_values(tokens, path, context)
|
||||
}
|
||||
|
||||
// prereq: root_path must be contextualized
|
||||
pub fn parse_values(
|
||||
mut tokens: Vec<Token>,
|
||||
root_path: impl AsRef<Path>,
|
||||
context: HashMap<String, String>
|
||||
) -> Result<Vec<Value>, ParsePresetError> {
|
||||
let mut root_path = root_path.as_ref().to_path_buf();
|
||||
if root_path.is_relative() {
|
||||
|
@ -239,7 +253,9 @@ pub fn parse_values(
|
|||
.collect();
|
||||
|
||||
// unfortunately we need to lex twice because there's no way to know the references ahead of time.
|
||||
let child_strings = load_child_reference_strings(references, &root_path)?;
|
||||
// the returned references should have context applied
|
||||
|
||||
let child_strings = load_child_reference_strings(references, &root_path, &context)?;
|
||||
let mut all_tokens: Vec<(&Path, Vec<Token>)> = Vec::new();
|
||||
|
||||
for (path, string) in child_strings.iter() {
|
||||
|
|
Loading…
Add table
Reference in a new issue