git.delta.rocks / jrsonnet / refs/commits / f7dfa48fc136

difftreelog

feat upgrade bindings to new importbin result

Yaroslav Bolyukin2022-11-20parent: #5876186.patch.diff
in: master

2 files changed

modifiedbindings/jsonnet/src/import.rsdiffbeforeafterboth
before · bindings/jsonnet/src/import.rs
1//! 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}
after · bindings/jsonnet/src/import.rs
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}
modifiedbindings/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> {