From 1589aaf7d716f6b723144d3cba95031c77dd2593 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Tue, 28 May 2019 18:24:02 -0500 Subject: [PATCH] Refactor: Use trait constraints instead of a trait object for our assets cache. --- src/build/format.rs | 22 ++++++++++++++++------ src/build/mod.rs | 23 ++++++++++++++++------- src/build/test.rs | 6 +++++- src/main.rs | 38 +++++++++++++++++++------------------- 4 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/build/format.rs b/src/build/format.rs index 736ff54..1d4e3df 100644 --- a/src/build/format.rs +++ b/src/build/format.rs @@ -19,6 +19,7 @@ use std::error::Error; use std::str::Chars; use crate::ast::*; +use crate::build::assets; use crate::build::{FileBuilder, Val}; use crate::error; @@ -85,13 +86,19 @@ impl + Clone> FormatRenderer for SimpleFormatter { } } -pub struct ExpressionFormatter<'a> { +pub struct ExpressionFormatter<'a, C> +where + C: assets::Cache, +{ tmpl: String, - builder: RefCell>, + builder: RefCell>, } -impl<'a> ExpressionFormatter<'a> { - pub fn new>(tmpl: S, builder: FileBuilder<'a>) -> Self { +impl<'a, C> ExpressionFormatter<'a, C> +where + C: assets::Cache, +{ + pub fn new>(tmpl: S, builder: FileBuilder<'a, C>) -> Self { ExpressionFormatter { tmpl: tmpl.into(), builder: RefCell::new(builder), @@ -100,7 +107,7 @@ impl<'a> ExpressionFormatter<'a> { fn consume_expr( &self, - builder: &mut FileBuilder, + builder: &mut FileBuilder<'a, C>, iter: &mut Chars, pos: &Position, ) -> Result> { @@ -176,7 +183,10 @@ impl<'a> ExpressionFormatter<'a> { } } -impl<'a> FormatRenderer for ExpressionFormatter<'a> { +impl<'a, C> FormatRenderer for ExpressionFormatter<'a, C> +where + C: assets::Cache, +{ fn render(&self, pos: &Position) -> Result> { let mut buf = String::new(); let mut should_escape = false; diff --git a/src/build/mod.rs b/src/build/mod.rs index c2a6cc7..29d651d 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -53,11 +53,14 @@ enum ProcessingOpType { impl FuncDef { /// Expands a ucg function using the given arguments into a new Val. - pub fn eval( + pub fn eval( &self, - parent_builder: &FileBuilder, + parent_builder: &FileBuilder, mut args: Vec>, - ) -> Result, Box> { + ) -> Result, Box> + where + C: assets::Cache, + { // Error conditions. If the args don't match the length and types of the argdefs then this is // func call error. if args.len() > self.argdefs.len() { @@ -98,7 +101,10 @@ pub struct AssertCollector { } /// Builder handles building ucg code for a single file. -pub struct FileBuilder<'a> { +pub struct FileBuilder<'a, C> +where + C: assets::Cache, +{ working_dir: PathBuf, std: Rc>, import_path: &'a Vec, @@ -117,7 +123,7 @@ pub struct FileBuilder<'a> { // are keyed by the canonicalized import path. This acts as a cache // so multiple imports of the same file don't have to be parsed // multiple times. - assets: Rc>, + assets: Rc>, pub is_module: bool, pub last: Option>, pub out_lock: Option<(String, Rc)>, @@ -141,12 +147,15 @@ macro_rules! eval_binary_expr { }; } -impl<'a> FileBuilder<'a> { +impl<'a, C> FileBuilder<'a, C> +where + C: assets::Cache, +{ /// Constructs a new Builder. pub fn new>( working_dir: P, import_paths: &'a Vec, - cache: Rc>, + cache: Rc>, ) -> Self { let env_vars: Vec<(String, String)> = env::vars().collect(); let scope = scope::Scope::new(Rc::new(Val::Env(env_vars))); diff --git a/src/build/test.rs b/src/build/test.rs index 0be293a..5c0c7c8 100644 --- a/src/build/test.rs +++ b/src/build/test.rs @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +use super::assets; use super::assets::MemoryCache; use super::{FileBuilder, SelectDef, Val}; use crate::ast::*; @@ -19,7 +20,10 @@ use std; use std::cell::RefCell; use std::rc::Rc; -fn test_expr_to_val(mut cases: Vec<(Expression, Val)>, b: FileBuilder) { +fn test_expr_to_val<'a, C: assets::Cache>( + mut cases: Vec<(Expression, Val)>, + b: FileBuilder<'a, C>, +) { for tpl in cases.drain(0..) { assert_eq!( b.eval_expr(&tpl.0, &b.scope.spawn_child()).unwrap(), diff --git a/src/main.rs b/src/main.rs index db08adb..8d98967 100644 --- a/src/main.rs +++ b/src/main.rs @@ -93,13 +93,13 @@ fn run_converter(c: &traits::Converter, v: Rc, f: Option<&str>) -> traits:: c.convert(v, file.as_mut()) } -fn build_file<'a>( +fn build_file<'a, C: Cache>( file: &'a str, validate: bool, strict: bool, import_paths: &'a Vec, - cache: Rc>, -) -> Result, Box> { + cache: Rc>, +) -> Result, Box> { let mut file_path_buf = PathBuf::from(file); if file_path_buf.is_relative() { file_path_buf = std::env::current_dir()?.join(file_path_buf); @@ -116,11 +116,11 @@ fn build_file<'a>( Ok(builder) } -fn do_validate( +fn do_validate( file: &str, strict: bool, import_paths: &Vec, - cache: Rc>, + cache: Rc>, ) -> bool { println!("Validating {}", file); match build_file(file, true, strict, import_paths, cache) { @@ -140,11 +140,11 @@ fn do_validate( return true; } -fn do_compile( +fn do_compile( file: &str, strict: bool, import_paths: &Vec, - cache: Rc>, + cache: Rc>, registry: &ConverterRegistry, ) -> bool { println!("Building {}", file); @@ -175,13 +175,13 @@ fn do_compile( } } -fn visit_ucg_files( +fn visit_ucg_files( path: &Path, recurse: bool, validate: bool, strict: bool, import_paths: &Vec, - cache: Rc>, + cache: Rc>, registry: &ConverterRegistry, ) -> Result> { let our_path = String::from(path.to_string_lossy()); @@ -252,10 +252,10 @@ fn visit_ucg_files( Ok(result) } -fn inspect_command( +fn inspect_command( matches: &clap::ArgMatches, import_paths: &Vec, - cache: Rc>, + cache: Rc>, registry: &ConverterRegistry, strict: bool, ) { @@ -315,10 +315,10 @@ fn inspect_command( } } -fn build_command( +fn build_command( matches: &clap::ArgMatches, import_paths: &Vec, - cache: Rc>, + cache: Rc>, registry: &ConverterRegistry, strict: bool, ) { @@ -414,10 +414,10 @@ fn fmt_command(matches: &clap::ArgMatches) -> std::result::Result<(), Box( matches: &clap::ArgMatches, import_paths: &Vec, - cache: Rc>, + cache: Rc>, registry: &ConverterRegistry, strict: bool, ) { @@ -513,9 +513,9 @@ fn env_help() { ); } -fn do_repl( +fn do_repl( import_paths: &Vec, - cache: Rc>, + cache: Rc>, ) -> std::result::Result<(), Box> { let config = rustyline::Config::builder(); let mut editor = rustyline::Editor::<()>::with_config( @@ -580,7 +580,7 @@ fn do_repl( } } -fn repl(import_paths: &Vec, cache: Rc>) { +fn repl(import_paths: &Vec, cache: Rc>) { if let Err(e) = do_repl(import_paths, cache) { eprintln!("{}", e); process::exit(1); @@ -590,7 +590,7 @@ fn repl(import_paths: &Vec, cache: Rc>) { fn main() { let mut app = do_flags(); let app_matches = app.clone().get_matches(); - let cache: Rc> = Rc::new(RefCell::new(MemoryCache::new())); + let cache = Rc::new(RefCell::new(MemoryCache::new())); let registry = ConverterRegistry::make_registry(); let mut import_paths = Vec::new(); if let Some(mut p) = dirs::home_dir() {