Skip to content

Commit

Permalink
refactor: receive Path in public api arguments
Browse files Browse the repository at this point in the history
Fixes #39
Fixes #47

Signed-off-by: Yaroslav Bolyukin <[email protected]>
  • Loading branch information
CertainLach committed Jun 14, 2021
1 parent ad64d8a commit ff2926d
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 108 deletions.
24 changes: 12 additions & 12 deletions bindings/jsonnet/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::{
fs::File,
io::Read,
os::raw::{c_char, c_int},
path::PathBuf,
path::{Path, PathBuf},
ptr::null_mut,
rc::Rc,
};
Expand All @@ -33,7 +33,7 @@ pub struct CallbackImportResolver {
out: RefCell<HashMap<PathBuf, IStr>>,
}
impl ImportResolver for CallbackImportResolver {
fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {
fn resolve_file(&self, from: &Path, path: &Path) -> Result<Rc<Path>> {
let base = CString::new(from.to_str().unwrap()).unwrap().into_raw();
let rel = CString::new(path.to_str().unwrap()).unwrap().into_raw();
let found_here: *mut c_char = null_mut();
Expand Down Expand Up @@ -73,9 +73,9 @@ impl ImportResolver for CallbackImportResolver {
unsafe { CString::from_raw(result_ptr) };
}

Ok(Rc::new(found_here_buf))
Ok(found_here_buf.into())
}
fn load_file_contents(&self, resolved: &PathBuf) -> Result<IStr> {
fn load_file_contents(&self, resolved: &Path) -> Result<IStr> {
Ok(self.out.borrow().get(resolved).unwrap().clone())
}
unsafe fn as_any(&self) -> &dyn Any {
Expand Down Expand Up @@ -108,27 +108,27 @@ impl NativeImportResolver {
}
}
impl ImportResolver for NativeImportResolver {
fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {
let mut new_path = from.clone();
fn resolve_file(&self, from: &Path, path: &Path) -> Result<Rc<Path>> {
let mut new_path = from.to_owned();
new_path.push(path);
if new_path.exists() {
Ok(Rc::new(new_path))
Ok(new_path.into())
} else {
for library_path in self.library_paths.borrow().iter() {
let mut cloned = library_path.clone();
cloned.push(path);
if cloned.exists() {
return Ok(Rc::new(cloned));
return Ok(cloned.into());
}
}
throw!(ImportFileNotFound(from.clone(), path.clone()))
throw!(ImportFileNotFound(from.to_owned(), path.to_owned()))
}
}
fn load_file_contents(&self, id: &PathBuf) -> Result<IStr> {
let mut file = File::open(id).map_err(|_e| ResolvedFileNotFound(id.clone()))?;
fn load_file_contents(&self, id: &Path) -> Result<IStr> {
let mut file = File::open(id).map_err(|_e| ResolvedFileNotFound(id.to_owned()))?;
let mut out = String::new();
file.read_to_string(&mut out)
.map_err(|_e| ImportBadFileUtf8(id.clone()))?;
.map_err(|_e| ImportBadFileUtf8(id.to_owned()))?;
Ok(out.into())
}
unsafe fn as_any(&self) -> &dyn Any {
Expand Down
7 changes: 3 additions & 4 deletions bindings/jsonnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use std::{
ffi::{CStr, CString},
os::raw::{c_char, c_double, c_int, c_uint},
path::PathBuf,
rc::Rc,
};

/// WASM stub
Expand Down Expand Up @@ -144,7 +143,7 @@ pub unsafe extern "C" fn jsonnet_evaluate_snippet(
let snippet = CStr::from_ptr(snippet);
match vm
.evaluate_snippet_raw(
Rc::new(PathBuf::from(filename.to_str().unwrap())),
PathBuf::from(filename.to_str().unwrap()).into(),
snippet.to_str().unwrap().into(),
)
.and_then(|v| vm.with_tla(v))
Expand Down Expand Up @@ -220,7 +219,7 @@ pub unsafe extern "C" fn jsonnet_evaluate_snippet_multi(
let snippet = CStr::from_ptr(snippet);
match vm
.evaluate_snippet_raw(
Rc::new(PathBuf::from(filename.to_str().unwrap())),
PathBuf::from(filename.to_str().unwrap()).into(),
snippet.to_str().unwrap().into(),
)
.and_then(|v| vm.with_tla(v))
Expand Down Expand Up @@ -294,7 +293,7 @@ pub unsafe extern "C" fn jsonnet_evaluate_snippet_stream(
let snippet = CStr::from_ptr(snippet);
match vm
.evaluate_snippet_raw(
Rc::new(PathBuf::from(filename.to_str().unwrap())),
PathBuf::from(filename.to_str().unwrap()).into(),
snippet.to_str().unwrap().into(),
)
.and_then(|v| vm.with_tla(v))
Expand Down
5 changes: 2 additions & 3 deletions cmds/jrsonnet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::{
io::Read,
io::Write,
path::PathBuf,
rc::Rc,
str::FromStr,
};

Expand Down Expand Up @@ -134,14 +133,14 @@ fn main_real(state: &EvaluationState, opts: Opts) -> Result<(), Error> {
let val = if opts.input.exec {
state.set_manifest_format(ManifestFormat::ToString);
state.evaluate_snippet_raw(
Rc::new(PathBuf::from("args")),
PathBuf::from("args").into(),
(&opts.input.input as &str).into(),
)?
} else if opts.input.input == "-" {
let mut input = Vec::new();
std::io::stdin().read_to_end(&mut input)?;
let input_str = std::str::from_utf8(&input)?.into();
state.evaluate_snippet_raw(Rc::new(PathBuf::from("<stdin>")), input_str)?
state.evaluate_snippet_raw(PathBuf::from("<stdin>").into(), input_str)?
} else {
state.evaluate_file_raw(&PathBuf::from(opts.input.input))?
};
Expand Down
2 changes: 1 addition & 1 deletion crates/jrsonnet-evaluator/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn main() {
let parsed = parse(
STDLIB_STR,
&ParserSettings {
file_name: Rc::new(PathBuf::from("std.jsonnet")),
file_name: PathBuf::from("std.jsonnet").into(),
loc_data: true,
},
)
Expand Down
2 changes: 1 addition & 1 deletion crates/jrsonnet-evaluator/src/builtin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ fn builtin_parse_json(
0, s: ty!(string) => Val::Str;
], {
let state = EvaluationState::default();
let path = Rc::new(PathBuf::from("std.parseJson"));
let path = PathBuf::from("std.parseJson").into();
state.evaluate_snippet_raw(path ,s)
})
}
Expand Down
4 changes: 2 additions & 2 deletions crates/jrsonnet-evaluator/src/builtin/stdlib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use jrsonnet_parser::{LocExpr, ParserSettings};
use std::{path::PathBuf, rc::Rc};
use std::path::PathBuf;

thread_local! {
/// To avoid parsing again when issued from the same thread
Expand All @@ -25,7 +25,7 @@ thread_local! {
jrsonnet_stdlib::STDLIB_STR,
&ParserSettings {
loc_data: true,
file_name: Rc::new(PathBuf::from("std.jsonnet")),
file_name: PathBuf::from("std.jsonnet").into(),
},
)
.unwrap()
Expand Down
7 changes: 5 additions & 2 deletions crates/jrsonnet-evaluator/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use crate::{
use jrsonnet_interner::IStr;
use jrsonnet_parser::{BinaryOpType, ExprLocation, UnaryOpType};
use jrsonnet_types::ValType;
use std::{path::PathBuf, rc::Rc};
use std::{
path::{Path, PathBuf},
rc::Rc,
};
use thiserror::Error;

#[derive(Error, Debug, Clone)]
Expand Down Expand Up @@ -86,7 +89,7 @@ pub enum Error {
.source_code.chars().nth(error.location.offset).map(|c| c.to_string()).unwrap_or_else(|| "EOF".into())
)]
ImportSyntaxError {
path: Rc<PathBuf>,
path: Rc<Path>,
source_code: IStr,
error: Box<jrsonnet_parser::ParseError>,
},
Expand Down
12 changes: 6 additions & 6 deletions crates/jrsonnet-evaluator/src/evaluate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,26 +609,26 @@ pub fn evaluate(context: Context, expr: &LocExpr) -> Result<Val> {
}
}
Import(path) => {
let mut tmp = loc
let tmp = loc
.clone()
.expect("imports cannot be used without loc_data")
.0;
let import_location = Rc::make_mut(&mut tmp);
let mut import_location = tmp.to_path_buf();
import_location.pop();
push(
loc.as_ref(),
|| format!("import {:?}", path),
|| with_state(|s| s.import_file(import_location, path)),
|| with_state(|s| s.import_file(&import_location, path)),
)?
}
ImportStr(path) => {
let mut tmp = loc
let tmp = loc
.clone()
.expect("imports cannot be used without loc_data")
.0;
let import_location = Rc::make_mut(&mut tmp);
let mut import_location = tmp.to_path_buf();
import_location.pop();
Val::Str(with_state(|s| s.import_file_str(import_location, path))?)
Val::Str(with_state(|s| s.import_file_str(&import_location, path))?)
}
})
}
48 changes: 27 additions & 21 deletions crates/jrsonnet-evaluator/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,23 @@ use fs::File;
use jrsonnet_interner::IStr;
use std::fs;
use std::io::Read;
use std::{any::Any, cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc};
use std::{
any::Any,
cell::RefCell,
collections::HashMap,
path::{Path, PathBuf},
rc::Rc,
};

/// Implements file resolution logic for `import` and `importStr`
pub trait ImportResolver {
/// Resolves real file path, e.g. `(/home/user/manifests, b.libjsonnet)` can correspond
/// both to `/home/user/manifests/b.libjsonnet` and to `/home/user/${vendor}/b.libjsonnet`
/// where `${vendor}` is a library path.
fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>>;
fn resolve_file(&self, from: &Path, path: &Path) -> Result<Rc<Path>>;

/// Reads file from filesystem, should be used only with path received from `resolve_file`
fn load_file_contents(&self, resolved: &PathBuf) -> Result<IStr>;
fn load_file_contents(&self, resolved: &Path) -> Result<IStr>;

/// # Safety
///
Expand All @@ -29,11 +35,11 @@ pub trait ImportResolver {
/// Dummy resolver, can't resolve/load any file
pub struct DummyImportResolver;
impl ImportResolver for DummyImportResolver {
fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {
throw!(ImportNotSupported(from.clone(), path.clone()))
fn resolve_file(&self, from: &Path, path: &Path) -> Result<Rc<Path>> {
throw!(ImportNotSupported(from.into(), path.into()))
}

fn load_file_contents(&self, _resolved: &PathBuf) -> Result<IStr> {
fn load_file_contents(&self, _resolved: &Path) -> Result<IStr> {
// Can be only caused by library direct consumer, not by supplied jsonnet
panic!("dummy resolver can't load any file")
}
Expand All @@ -57,27 +63,27 @@ pub struct FileImportResolver {
pub library_paths: Vec<PathBuf>,
}
impl ImportResolver for FileImportResolver {
fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {
let mut new_path = from.clone();
new_path.push(path);
if new_path.exists() {
Ok(Rc::new(new_path))
fn resolve_file(&self, from: &Path, path: &Path) -> Result<Rc<Path>> {
let mut direct = from.to_path_buf();
direct.push(path);
if direct.exists() {
Ok(direct.into())
} else {
for library_path in self.library_paths.iter() {
let mut cloned = library_path.clone();
cloned.push(path);
if cloned.exists() {
return Ok(Rc::new(cloned));
return Ok(cloned.into());
}
}
throw!(ImportFileNotFound(from.clone(), path.clone()))
throw!(ImportFileNotFound(from.to_owned(), path.to_owned()))
}
}
fn load_file_contents(&self, id: &PathBuf) -> Result<IStr> {
let mut file = File::open(id).map_err(|_e| ResolvedFileNotFound(id.clone()))?;
fn load_file_contents(&self, id: &Path) -> Result<IStr> {
let mut file = File::open(id).map_err(|_e| ResolvedFileNotFound(id.to_owned()))?;
let mut out = String::new();
file.read_to_string(&mut out)
.map_err(|_e| ImportBadFileUtf8(id.clone()))?;
.map_err(|_e| ImportBadFileUtf8(id.to_owned()))?;
Ok(out.into())
}
unsafe fn as_any(&self) -> &dyn Any {
Expand All @@ -89,23 +95,23 @@ type ResolutionData = (PathBuf, PathBuf);

/// Caches results of the underlying resolver
pub struct CachingImportResolver {
resolution_cache: RefCell<HashMap<ResolutionData, Result<Rc<PathBuf>>>>,
resolution_cache: RefCell<HashMap<ResolutionData, Result<Rc<Path>>>>,
loading_cache: RefCell<HashMap<PathBuf, Result<IStr>>>,
inner: Box<dyn ImportResolver>,
}
impl ImportResolver for CachingImportResolver {
fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {
fn resolve_file(&self, from: &Path, path: &Path) -> Result<Rc<Path>> {
self.resolution_cache
.borrow_mut()
.entry((from.clone(), path.clone()))
.entry((from.to_owned(), path.to_owned()))
.or_insert_with(|| self.inner.resolve_file(from, path))
.clone()
}

fn load_file_contents(&self, resolved: &PathBuf) -> Result<IStr> {
fn load_file_contents(&self, resolved: &Path) -> Result<IStr> {
self.loading_cache
.borrow_mut()
.entry(resolved.clone())
.entry(resolved.to_owned())
.or_insert_with(|| self.inner.load_file_contents(resolved))
.clone()
}
Expand Down
Loading

0 comments on commit ff2926d

Please sign in to comment.