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 std::path::Path;
|
||||||
|
|
||||||
use nom_locate::LocatedSpan;
|
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 {
|
impl ShaderPreset {
|
||||||
/// Try to parse the shader preset at the given path.
|
/// Try to parse the shader preset at the given path.
|
||||||
pub fn try_parse(path: impl AsRef<Path>) -> Result<ShaderPreset, ParsePresetError> {
|
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))
|
Ok(resolve_values(values))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{ScaleFactor, ScaleType};
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
use nom::character::complete::digit1;
|
use nom::character::complete::digit1;
|
||||||
use nom::combinator::{eof, map_res};
|
use nom::combinator::{eof, map_res};
|
||||||
use std::collections::VecDeque;
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
use num_traits::cast::ToPrimitive;
|
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;
|
pub const SHADER_MAX_REFERENCE_DEPTH: usize = 16;
|
||||||
|
|
||||||
|
// prereq: root_path must be contextualized
|
||||||
fn load_child_reference_strings(
|
fn load_child_reference_strings(
|
||||||
root_references: Vec<PathBuf>,
|
root_references: Vec<PathBuf>,
|
||||||
root_path: impl AsRef<Path>,
|
root_path: impl AsRef<Path>,
|
||||||
|
context: &HashMap<String, String>
|
||||||
) -> Result<Vec<(PathBuf, String)>, ParsePresetError> {
|
) -> Result<Vec<(PathBuf, String)>, ParsePresetError> {
|
||||||
let root_path = root_path.as_ref();
|
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 root_references = vec![(root_path.to_path_buf(), root_references)];
|
||||||
let mut root_references = VecDeque::from(root_references);
|
let mut root_references = VecDeque::from(root_references);
|
||||||
// search needs to be depth first to allow for overrides.
|
// 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 {
|
if reference_depth > SHADER_MAX_REFERENCE_DEPTH {
|
||||||
return Err(ParsePresetError::ExceededReferenceDepth);
|
return Err(ParsePresetError::ExceededReferenceDepth);
|
||||||
}
|
}
|
||||||
// enter the current root
|
// enter the current root
|
||||||
reference_depth += 1;
|
reference_depth += 1;
|
||||||
// canonicalize current root
|
// canonicalize current root
|
||||||
|
apply_context(&mut reference_root, context);
|
||||||
let reference_root = reference_root
|
let reference_root = reference_root
|
||||||
.canonicalize()
|
.canonicalize()
|
||||||
.map_err(|e| ParsePresetError::IOError(reference_root.to_path_buf(), e))?;
|
.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 {
|
for path in referenced_paths {
|
||||||
let mut path = reference_root
|
let mut path = reference_root
|
||||||
.join(path.clone())
|
.join(path.clone());
|
||||||
.canonicalize()
|
apply_context(&mut path, context);
|
||||||
|
|
||||||
|
let mut path = path.canonicalize()
|
||||||
.map_err(|e| ParsePresetError::IOError(path.clone(), e))?;
|
.map_err(|e| ParsePresetError::IOError(path.clone(), e))?;
|
||||||
// println!("Opening {:?}", path);
|
// println!("Opening {:?}", path);
|
||||||
let mut reference_contents = String::new();
|
let mut reference_contents = String::new();
|
||||||
|
@ -204,8 +209,15 @@ fn load_child_reference_strings(
|
||||||
Ok(reference_strings.into())
|
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 path = path.as_ref();
|
||||||
|
let mut path = path.to_path_buf();
|
||||||
|
apply_context(&mut path, &context);
|
||||||
|
|
||||||
let path = path
|
let path = path
|
||||||
.canonicalize()
|
.canonicalize()
|
||||||
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
|
.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))?;
|
.map_err(|e| ParsePresetError::IOError(path.to_path_buf(), e))?;
|
||||||
|
|
||||||
let tokens = super::token::do_lex(&contents)?;
|
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(
|
pub fn parse_values(
|
||||||
mut tokens: Vec<Token>,
|
mut tokens: Vec<Token>,
|
||||||
root_path: impl AsRef<Path>,
|
root_path: impl AsRef<Path>,
|
||||||
|
context: HashMap<String, String>
|
||||||
) -> Result<Vec<Value>, ParsePresetError> {
|
) -> Result<Vec<Value>, ParsePresetError> {
|
||||||
let mut root_path = root_path.as_ref().to_path_buf();
|
let mut root_path = root_path.as_ref().to_path_buf();
|
||||||
if root_path.is_relative() {
|
if root_path.is_relative() {
|
||||||
|
@ -239,7 +253,9 @@ pub fn parse_values(
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// unfortunately we need to lex twice because there's no way to know the references ahead of time.
|
// 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();
|
let mut all_tokens: Vec<(&Path, Vec<Token>)> = Vec::new();
|
||||||
|
|
||||||
for (path, string) in child_strings.iter() {
|
for (path, string) in child_strings.iter() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue