difftreelog
feat upgrade bindings to new importbin result
in: master
2 files changed
bindings/jsonnet/src/import.rsdiffbeforeafterboth1//! Import resolution manipulation utilities23use std::{4 any::Any,5 cell::RefCell,6 collections::HashMap,7 env::current_dir,8 ffi::{c_void, CStr, CString},9 os::raw::{c_char, c_int},10 path::PathBuf,11 ptr::null_mut,12};1314use jrsonnet_evaluator::{15 error::{ErrorKind::*, Result},16 throw, FileImportResolver, ImportResolver,17};18use jrsonnet_gcmodule::Trace;19use jrsonnet_parser::{SourceDirectory, SourceFile, SourcePath};2021use crate::VM;2223pub type JsonnetImportCallback = unsafe extern "C" fn(24 ctx: *mut c_void,25 base: *const c_char,26 rel: *const c_char,27 found_here: *mut *const c_char,28 success: &mut c_int,29) -> *mut c_char;3031/// Resolves imports using callback32#[derive(Trace)]33pub struct CallbackImportResolver {34 #[trace(skip)]35 cb: JsonnetImportCallback,36 #[trace(skip)]37 ctx: *mut c_void,38 out: RefCell<HashMap<SourcePath, Vec<u8>>>,39}40impl ImportResolver for CallbackImportResolver {41 fn resolve_from(&self, from: &SourcePath, path: &str) -> Result<SourcePath> {42 let base = if let Some(p) = from.downcast_ref::<SourceFile>() {43 let mut o = p.path().to_owned();44 o.pop();45 o46 } else if let Some(d) = from.downcast_ref::<SourceDirectory>() {47 d.path().to_owned()48 } else if from.is_default() {49 current_dir().map_err(|e| ImportIo(e.to_string()))?50 } else {51 unreachable!("can't resolve this path");52 };53 let base = unsafe { crate::unparse_path(&base) };54 let rel = CString::new(path).unwrap();55 let found_here: *mut c_char = null_mut();56 let mut success: i32 = 0;57 let result_ptr = unsafe {58 (self.cb)(59 self.ctx,60 base.as_ptr(),61 rel.as_ptr(),62 &mut (found_here as *const _),63 &mut success,64 )65 };66 let result_raw = unsafe { CStr::from_ptr(result_ptr) };67 let result_str = result_raw.to_str().unwrap();68 assert!(success == 0 || success == 1);69 if success == 0 {70 unsafe { CString::from_raw(result_ptr) };71 let result = result_str.to_owned();72 throw!(ImportCallbackError(result));73 }7475 let found_here_raw = unsafe { CStr::from_ptr(found_here) };76 let found_here_buf = SourcePath::new(SourceFile::new(PathBuf::from(77 found_here_raw.to_str().unwrap(),78 )));79 unsafe {80 let _ = CString::from_raw(found_here);81 }8283 let mut out = self.out.borrow_mut();84 if !out.contains_key(&found_here_buf) {85 out.insert(found_here_buf.clone(), result_str.into());86 unsafe { CString::from_raw(result_ptr) };87 }8889 Ok(found_here_buf)90 }91 fn load_file_contents(&self, resolved: &SourcePath) -> Result<Vec<u8>> {92 Ok(self.out.borrow().get(resolved).unwrap().clone())93 }9495 fn as_any(&self) -> &dyn Any {96 self97 }98}99100/// # Safety101///102/// It should be safe to call `cb` using valid values with passed `ctx`103#[no_mangle]104pub unsafe extern "C" fn jsonnet_import_callback(105 vm: &VM,106 cb: JsonnetImportCallback,107 ctx: *mut c_void,108) {109 vm.state110 .set_import_resolver(Box::new(CallbackImportResolver {111 cb,112 ctx,113 out: RefCell::new(HashMap::new()),114 }))115}116117/// # Safety118///119/// `path` should be a NUL-terminated string120#[no_mangle]121pub unsafe extern "C" fn jsonnet_jpath_add(vm: &VM, path: *const c_char) {122 let cstr = CStr::from_ptr(path);123 let path = PathBuf::from(cstr.to_str().unwrap());124 let any_resolver = vm.state.import_resolver();125 let resolver = any_resolver126 .as_any()127 .downcast_ref::<FileImportResolver>()128 .expect("jpaths are not compatible with callback imports!");129 resolver.add_jpath(path);130}1//! Import resolution manipulation utilities23use std::{4 alloc::Layout,5 any::Any,6 cell::RefCell,7 collections::HashMap,8 env::current_dir,9 ffi::{c_void, CStr, CString},10 os::raw::{c_char, c_int},11 path::PathBuf,12 ptr::null_mut,13};1415use jrsonnet_evaluator::{16 error::{ErrorKind::*, Result},17 throw, FileImportResolver, ImportResolver,18};19use jrsonnet_gcmodule::Trace;20use jrsonnet_parser::{SourceDirectory, SourceFile, SourcePath};2122use crate::VM;2324pub type JsonnetImportCallback = unsafe extern "C" fn(25 ctx: *mut c_void,26 base: *const c_char,27 rel: *const c_char,28 found_here: *mut *const c_char,29 buf: *mut *mut c_char,30 buflen: *mut usize,31) -> c_int;3233/// Resolves imports using callback34#[derive(Trace)]35pub struct CallbackImportResolver {36 #[trace(skip)]37 cb: JsonnetImportCallback,38 #[trace(skip)]39 ctx: *mut c_void,40 out: RefCell<HashMap<SourcePath, Vec<u8>>>,41}42impl ImportResolver for CallbackImportResolver {43 fn resolve_from(&self, from: &SourcePath, path: &str) -> Result<SourcePath> {44 let base = if let Some(p) = from.downcast_ref::<SourceFile>() {45 let mut o = p.path().to_owned();46 o.pop();47 o48 } else if let Some(d) = from.downcast_ref::<SourceDirectory>() {49 d.path().to_owned()50 } else if from.is_default() {51 current_dir().map_err(|e| ImportIo(e.to_string()))?52 } else {53 unreachable!("can't resolve this path");54 };55 let base = unsafe { crate::unparse_path(&base) };56 let rel = CString::new(path).unwrap();57 let found_here: *mut c_char = null_mut();5859 let mut buf = null_mut();60 let mut buf_len = 0;61 let success = unsafe {62 (self.cb)(63 self.ctx,64 base.as_ptr(),65 rel.as_ptr(),66 &mut (found_here as *const _),67 &mut buf,68 &mut buf_len,69 )70 };71 let buf_slice: &[u8] = unsafe { std::slice::from_raw_parts(buf.cast(), buf_len) };72 unsafe {73 std::alloc::dealloc(74 buf.cast(),75 Layout::from_size_align(buf_len, 1).expect("layout is valid"),76 );77 };78 let buf_intern = buf_slice.to_vec();7980 assert!(success == 0 || success == 1);81 if success == 0 {82 let result = String::from_utf8(buf_intern).expect("error should be valid string");83 throw!(ImportCallbackError(result));84 }8586 let found_here_raw = unsafe { CStr::from_ptr(found_here) };87 let found_here_buf = SourcePath::new(SourceFile::new(PathBuf::from(88 found_here_raw.to_str().unwrap(),89 )));90 unsafe {91 let _ = CString::from_raw(found_here);92 }9394 let mut out = self.out.borrow_mut();95 if !out.contains_key(&found_here_buf) {96 out.insert(found_here_buf.clone(), buf_intern);97 }9899 Ok(found_here_buf)100 }101 fn load_file_contents(&self, resolved: &SourcePath) -> Result<Vec<u8>> {102 Ok(self.out.borrow().get(resolved).unwrap().clone())103 }104105 fn as_any(&self) -> &dyn Any {106 self107 }108}109110/// # Safety111///112/// It should be safe to call `cb` using valid values with passed `ctx`113#[no_mangle]114pub unsafe extern "C" fn jsonnet_import_callback(115 vm: &VM,116 cb: JsonnetImportCallback,117 ctx: *mut c_void,118) {119 vm.state120 .set_import_resolver(Box::new(CallbackImportResolver {121 cb,122 ctx,123 out: RefCell::new(HashMap::new()),124 }))125}126127/// # Safety128///129/// `path` should be a NUL-terminated string130#[no_mangle]131pub unsafe extern "C" fn jsonnet_jpath_add(vm: &VM, path: *const c_char) {132 let cstr = CStr::from_ptr(path);133 let path = PathBuf::from(cstr.to_str().unwrap());134 let any_resolver = vm.state.import_resolver();135 let resolver = any_resolver136 .as_any()137 .downcast_ref::<FileImportResolver>()138 .expect("jpaths are not compatible with callback imports!");139 resolver.add_jpath(path);140}bindings/jsonnet/src/lib.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/lib.rs
+++ b/bindings/jsonnet/src/lib.rs
@@ -40,7 +40,7 @@
/// then there is a mismatch between header and compiled library.
#[no_mangle]
pub extern "C" fn jsonnet_version() -> &'static [u8; 8] {
- b"v0.16.0\0"
+ b"v0.19.1\0"
}
unsafe fn parse_path(input: &CStr) -> Cow<Path> {