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

difftreelog

feat(bindings) jpath api

Лач2020-06-28parent: #789bed1.patch.diff
in: master

1 file changed

modifiedbindings/jsonnet/src/lib.rsdiffbeforeafterboth
before · bindings/jsonnet/src/lib.rs
1use jrsonnet_evaluator::{EvaluationState, ObjValue, Val};2use libc::{c_char, c_double, c_int, c_uint};3use std::{4	ffi::{CStr, CString},5	path::PathBuf,6	rc::Rc,7};89#[no_mangle]10pub extern "C" fn jsonnet_version() -> &'static [u8; 8] {11	b"v0.16.0\0"12}1314#[no_mangle]15pub extern "C" fn jsonnet_make() -> Box<EvaluationState> {16	Box::new(EvaluationState::default())17}1819// TODO20#[no_mangle]21pub extern "C" fn jsonnet_max_stack(_vm: &EvaluationState, _v: c_uint) {}2223// jrsonnet currently have no GC, so these functions is no-op24#[no_mangle]25pub extern "C" fn jsonnet_gc_min_objects(_vm: &EvaluationState, _v: c_uint) {}26#[no_mangle]27pub extern "C" fn jsonnet_gc_growth_trigger(_vm: &EvaluationState, _v: c_double) {}2829// TODO30#[no_mangle]31pub extern "C" fn jsonnet_string_output(_vm: &EvaluationState, _v: c_int) {}3233#[no_mangle]34pub extern "C" fn jsonnet_json_extract_string(_vm: &EvaluationState, v: &Val) -> *mut c_char {35	match v.unwrap_if_lazy().unwrap() {36		Val::Str(s) => CString::new(&*s as &str).unwrap().into_raw(),37		_ => std::ptr::null_mut(),38	}39}40#[no_mangle]41pub extern "C" fn jsonnet_json_extract_number(42	_vm: &EvaluationState,43	v: &Val,44	out: &mut c_double,45) -> c_int {46	match v.unwrap_if_lazy().unwrap() {47		Val::Num(n) => {48			*out = n;49			150		}51		_ => 0,52	}53}54#[no_mangle]55pub extern "C" fn jsonnet_json_extract_bool(_vm: &EvaluationState, v: &Val) -> c_int {56	match v.unwrap_if_lazy().unwrap() {57		Val::Bool(false) => 0,58		Val::Bool(true) => 1,59		_ => 2,60	}61}62#[no_mangle]63pub extern "C" fn jsonnet_json_extract_null(_vm: &EvaluationState, v: &Val) -> c_int {64	match v.unwrap_if_lazy().unwrap() {65		Val::Null => 1,66		_ => 0,67	}68}6970/// # Safety71///72/// This function is safe, if received v is a pointer to normal C string73#[no_mangle]74pub unsafe extern "C" fn jsonnet_json_make_string(75	_vm: &EvaluationState,76	v: *const c_char,77) -> Box<Val> {78	let cstr = CStr::from_ptr(v);79	let str = cstr.to_str().unwrap();80	Box::new(Val::Str(str.into()))81}8283#[no_mangle]84pub extern "C" fn jsonnet_json_make_number(_vm: &EvaluationState, v: c_double) -> Box<Val> {85	Box::new(Val::Num(v))86}8788#[no_mangle]89pub extern "C" fn jsonnet_json_make_bool(_vm: &EvaluationState, v: c_int) -> Box<Val> {90	assert!(v == 0 || v == 1);91	Box::new(Val::Bool(v == 1))92}9394#[no_mangle]95pub extern "C" fn jsonnet_json_make_null(_vm: &EvaluationState) -> Box<Val> {96	Box::new(Val::Null)97}9899#[no_mangle]100pub extern "C" fn jsonnet_json_make_array(_vm: &EvaluationState) -> Box<Val> {101	Box::new(Val::Arr(Rc::new(Vec::new())))102}103104#[no_mangle]105pub extern "C" fn jsonnet_json_array_append(_vm: &EvaluationState, arr: &mut Val, val: &Val) {106	match arr {107		Val::Arr(old) => {108			let mut new = Vec::new();109			new.extend(old.iter().cloned());110			new.push(val.clone());111			*arr = Val::Arr(Rc::new(new));112		}113		_ => panic!("should receive array"),114	}115}116117#[no_mangle]118pub extern "C" fn jsonnet_json_make_object(_vm: &EvaluationState) -> Box<Val> {119	Box::new(Val::Obj(ObjValue::new_empty()))120}121122#[no_mangle]123pub extern "C" fn jsonnet_json_object_append(124	_vm: &EvaluationState,125	_obj: &mut Val,126	_name: *const c_char,127	_val: &Val,128) {129	todo!()130}131132#[no_mangle]133pub extern "C" fn jsonnet_realloc(_vm: &EvaluationState, _buf: *const u8, _sz: usize) -> *const u8 {134	todo!()135}136137#[no_mangle]138#[allow(clippy::boxed_local)]139pub extern "C" fn jsonnet_json_destroy(_vm: &EvaluationState, _v: Box<Val>) {}140141#[no_mangle]142pub extern "C" fn jsonnet_import_callback() {143	todo!()144}145#[no_mangle]146pub extern "C" fn jsonnet_native_callback() {147	todo!()148}149#[no_mangle]150pub extern "C" fn jsonnet_ext_var() {151	todo!()152}153#[no_mangle]154pub extern "C" fn jsonnet_ext_code() {155	todo!()156}157#[no_mangle]158pub extern "C" fn jsonnet_tla_var() {159	todo!()160}161#[no_mangle]162pub extern "C" fn jsonnet_tla_code() {163	todo!()164}165#[no_mangle]166pub extern "C" fn jsonnet_max_trace() {167	todo!()168}169#[no_mangle]170pub extern "C" fn jsonnet_jpath_add() {171	todo!()172}173174/// # Safety175///176/// This function is safe, if received v is a pointer to normal C string177#[no_mangle]178pub unsafe extern "C" fn jsonnet_evaluate_file(179	vm: &EvaluationState,180	filename: *const c_char,181	error: &mut c_int,182) -> *const c_char {183	vm.run_in_state(|| {184		use std::fmt::Write;185		let filename = CStr::from_ptr(filename);186		match vm.evaluate_file_to_json(&PathBuf::from(filename.to_str().unwrap())) {187			Ok(v) => {188				*error = 0;189				CString::new(&*v as &str).unwrap().into_raw()190			}191			Err(e) => {192				*error = 1;193				let mut out = String::new();194				writeln!(out, "{:?}", e.0).unwrap();195				for i in (e.1).0.iter() {196					writeln!(out, "{:?}", i).unwrap();197				}198				CString::new(&out as &str).unwrap().into_raw()199			}200		}201	})202}203#[no_mangle]204pub extern "C" fn jsonnet_evaluate_snippet() {205	todo!()206}207#[no_mangle]208pub extern "C" fn jsonnet_evaluate_file_multi() {209	todo!()210}211#[no_mangle]212pub extern "C" fn jsonnet_evaluate_snippet_multi() {213	todo!()214}215#[no_mangle]216pub extern "C" fn jsonnet_evaluate_file_stream() {217	todo!()218}219#[no_mangle]220pub extern "C" fn jsonnet_evaluate_snippet_stream() {221	todo!()222}223224#[no_mangle]225#[allow(clippy::boxed_local)]226pub extern "C" fn jsonnet_destroy(_vm: Box<EvaluationState>) {}
after · bindings/jsonnet/src/lib.rs
1use jrsonnet_evaluator::{2	create_error, create_error_result, Error, EvaluationState, ImportResolver, LazyBinding,3	LazyVal, ObjMember, ObjValue, Result, Val,4};5use jrsonnet_parser::Visibility;6use libc::{c_char, c_double, c_int, c_uint};7use std::{8	alloc::Layout,9	any::Any,10	cell::RefCell,11	collections::BTreeMap,12	ffi::{CStr, CString},13	fs::File,14	io::Read,15	path::PathBuf,16	rc::Rc,17};1819#[no_mangle]20pub extern "C" fn jsonnet_version() -> &'static [u8; 8] {21	b"v0.16.0\0"22}2324#[derive(Default)]25struct NativeImportResolver {26	library_paths: RefCell<Vec<PathBuf>>,27}28impl NativeImportResolver {29	fn add_jpath(&self, path: PathBuf) {30		self.library_paths.borrow_mut().push(path);31	}32}33impl ImportResolver for NativeImportResolver {34	fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {35		let mut new_path = from.clone();36		new_path.push(path);37		if new_path.exists() {38			Ok(Rc::new(new_path))39		} else {40			for library_path in self.library_paths.borrow().iter() {41				let mut cloned = library_path.clone();42				cloned.push(path);43				if cloned.exists() {44					return Ok(Rc::new(cloned));45				}46			}47			create_error_result(Error::ImportFileNotFound(from.clone(), path.clone()))48		}49	}50	fn load_file_contents(&self, id: &PathBuf) -> Result<Rc<str>> {51		let mut file =52			File::open(id).map_err(|_e| create_error(Error::ResolvedFileNotFound(id.clone())))?;53		let mut out = String::new();54		file.read_to_string(&mut out)55			.map_err(|_e| create_error(Error::ImportBadFileUtf8(id.clone())))?;56		Ok(out.into())57	}58	unsafe fn as_any(&self) -> &dyn Any {59		self60	}61}6263#[no_mangle]64pub extern "C" fn jsonnet_make() -> Box<EvaluationState> {65	let state = EvaluationState::default();66	state.with_stdlib();67	state.set_import_resolver(Box::new(NativeImportResolver::default()));68	Box::new(state)69}7071// TODO72#[no_mangle]73pub extern "C" fn jsonnet_max_stack(_vm: &EvaluationState, _v: c_uint) {}7475// jrsonnet currently have no GC, so these functions is no-op76#[no_mangle]77pub extern "C" fn jsonnet_gc_min_objects(_vm: &EvaluationState, _v: c_uint) {}78#[no_mangle]79pub extern "C" fn jsonnet_gc_growth_trigger(_vm: &EvaluationState, _v: c_double) {}8081// TODO82#[no_mangle]83pub extern "C" fn jsonnet_string_output(_vm: &EvaluationState, _v: c_int) {}8485#[no_mangle]86pub extern "C" fn jsonnet_json_extract_string(_vm: &EvaluationState, v: &Val) -> *mut c_char {87	match v.unwrap_if_lazy().unwrap() {88		Val::Str(s) => CString::new(&*s as &str).unwrap().into_raw(),89		_ => std::ptr::null_mut(),90	}91}92#[no_mangle]93pub extern "C" fn jsonnet_json_extract_number(94	_vm: &EvaluationState,95	v: &Val,96	out: &mut c_double,97) -> c_int {98	match v.unwrap_if_lazy().unwrap() {99		Val::Num(n) => {100			*out = n;101			1102		}103		_ => 0,104	}105}106#[no_mangle]107pub extern "C" fn jsonnet_json_extract_bool(_vm: &EvaluationState, v: &Val) -> c_int {108	match v.unwrap_if_lazy().unwrap() {109		Val::Bool(false) => 0,110		Val::Bool(true) => 1,111		_ => 2,112	}113}114#[no_mangle]115pub extern "C" fn jsonnet_json_extract_null(_vm: &EvaluationState, v: &Val) -> c_int {116	match v.unwrap_if_lazy().unwrap() {117		Val::Null => 1,118		_ => 0,119	}120}121122/// # Safety123///124/// This function is safe, if received v is a pointer to normal C string125#[no_mangle]126pub unsafe extern "C" fn jsonnet_json_make_string(127	_vm: &EvaluationState,128	v: *const c_char,129) -> Box<Val> {130	let cstr = CStr::from_ptr(v);131	let str = cstr.to_str().unwrap();132	Box::new(Val::Str(str.into()))133}134135#[no_mangle]136pub extern "C" fn jsonnet_json_make_number(_vm: &EvaluationState, v: c_double) -> Box<Val> {137	Box::new(Val::Num(v))138}139140#[no_mangle]141pub extern "C" fn jsonnet_json_make_bool(_vm: &EvaluationState, v: c_int) -> Box<Val> {142	assert!(v == 0 || v == 1);143	Box::new(Val::Bool(v == 1))144}145146#[no_mangle]147pub extern "C" fn jsonnet_json_make_null(_vm: &EvaluationState) -> Box<Val> {148	Box::new(Val::Null)149}150151#[no_mangle]152pub extern "C" fn jsonnet_json_make_array(_vm: &EvaluationState) -> Box<Val> {153	Box::new(Val::Arr(Rc::new(Vec::new())))154}155156#[no_mangle]157pub extern "C" fn jsonnet_json_array_append(_vm: &EvaluationState, arr: &mut Val, val: &Val) {158	match arr {159		Val::Arr(old) => {160			let mut new = Vec::new();161			new.extend(old.iter().cloned());162			new.push(val.clone());163			*arr = Val::Arr(Rc::new(new));164		}165		_ => panic!("should receive array"),166	}167}168169#[no_mangle]170pub extern "C" fn jsonnet_json_make_object(_vm: &EvaluationState) -> Box<Val> {171	Box::new(Val::Obj(ObjValue::new_empty()))172}173174#[no_mangle]175pub extern "C" fn jsonnet_json_object_append(176	_vm: &EvaluationState,177	_obj: &mut Val,178	_name: *const c_char,179	_val: &Val,180) {181	todo!()182}183184#[no_mangle]185pub extern "C" fn jsonnet_realloc(_vm: &EvaluationState, _buf: *const u8, _sz: usize) -> *const u8 {186	todo!()187}188189#[no_mangle]190#[allow(clippy::boxed_local)]191pub extern "C" fn jsonnet_json_destroy(_vm: &EvaluationState, _v: Box<Val>) {}192193#[no_mangle]194pub extern "C" fn jsonnet_import_callback() {195	todo!()196}197#[no_mangle]198pub extern "C" fn jsonnet_native_callback() {199	todo!()200}201#[no_mangle]202pub extern "C" fn jsonnet_ext_var() {203	todo!()204}205#[no_mangle]206pub extern "C" fn jsonnet_ext_code() {207	todo!()208}209#[no_mangle]210pub extern "C" fn jsonnet_tla_var() {211	todo!()212}213#[no_mangle]214pub extern "C" fn jsonnet_tla_code() {215	todo!()216}217#[no_mangle]218pub extern "C" fn jsonnet_max_trace() {219	todo!()220}221222/// # Safety223///224/// This function is safe, if received v is a pointer to normal C string225#[no_mangle]226pub unsafe extern "C" fn jsonnet_jpath_add(vm: &EvaluationState, v: *const c_char) {227	let cstr = CStr::from_ptr(v);228	let path = PathBuf::from(cstr.to_str().unwrap());229	let any_resolver = vm.import_resolver();230	let resolver = any_resolver231		.as_any()232		.downcast_ref::<NativeImportResolver>()233		.unwrap();234	resolver.add_jpath(path);235}236237/// # Safety238///239/// This function is safe, if received v is a pointer to normal C string240#[no_mangle]241pub unsafe extern "C" fn jsonnet_evaluate_file(242	vm: &EvaluationState,243	filename: *const c_char,244	error: &mut c_int,245) -> *const c_char {246	vm.run_in_state(|| {247		use std::fmt::Write;248		let filename = CStr::from_ptr(filename);249		match vm.evaluate_file_to_json(&PathBuf::from(filename.to_str().unwrap())) {250			Ok(v) => {251				*error = 0;252				CString::new(&*v as &str).unwrap().into_raw()253			}254			Err(e) => {255				*error = 1;256				let mut out = String::new();257				writeln!(out, "{:?}", e.0).unwrap();258				for i in (e.1).0.iter() {259					writeln!(out, "{:?}", i).unwrap();260				}261				CString::new(&out as &str).unwrap().into_raw()262			}263		}264	})265}266#[no_mangle]267pub extern "C" fn jsonnet_evaluate_snippet() {268	todo!()269}270#[no_mangle]271pub extern "C" fn jsonnet_evaluate_file_multi() {272	todo!()273}274#[no_mangle]275pub extern "C" fn jsonnet_evaluate_snippet_multi() {276	todo!()277}278#[no_mangle]279pub extern "C" fn jsonnet_evaluate_file_stream() {280	todo!()281}282#[no_mangle]283pub extern "C" fn jsonnet_evaluate_snippet_stream() {284	todo!()285}286287#[no_mangle]288#[allow(clippy::boxed_local)]289pub extern "C" fn jsonnet_destroy(_vm: Box<EvaluationState>) {}