#[cfg(all(test, feature = "jlrs-derive", feature = "local-rt"))] mod derive_util; #[cfg(all(test, feature = "jlrs-derive", feature = "local-rt"))] mod tests { use std::os::raw::c_void; use jlrs::{ data::{ layout::{ julia_enum::Enum, valid_layout::{ValidField, ValidLayout}, }, types::construct_type::{ConstantBool, ConstructType}, }, prelude::*, }; use super::derive_util::{derive_impls::*, JULIA_DERIVE}; fn derive_bits_type_bool() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeBool { a: Bool::new(true) }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap().as_bool(), true); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_elided() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let a = HasElidedParam { a: 3.0 }; type ElidedParam = HasElidedParamTypeConstructor>; let v = unsafe { Value::try_new_with::, _, _>(&mut frame, a)? }; assert!(v.is::>()); assert!(v.unbox::>().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_elided_with_ptr() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let main_mod = Module::main(&frame).as_ref(); let a = HasElidedParam { a: Some(main_mod) }; type ElidedParam = HasElidedParamTypeConstructor>; let v = unsafe { Value::try_new_with::, _, _>(&mut frame, a)? }; assert!(v.is::>>()); assert!(v.unbox::>>().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_double_variant() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "DoubleVariant")? .as_managed() .cast::()?; let v2 = Value::new(&mut frame, 2i16); let jl_val = constr .instantiate(&mut frame, &mut [v2])? .into_jlrs_result()?; assert!(jl_val.datatype().is::()); let field = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(field.unbox::().unwrap(), 2); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn rebox_double_variant() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "DoubleVariant")? .as_managed() .cast::()?; let v2 = Value::new(&mut frame, 2i16); let jl_val = constr .instantiate(&mut frame, &mut [v2])? .into_jlrs_result()?; let unboxed = jl_val.unbox::()?; assert!( Value::try_new_with::(&mut frame, unboxed).is_ok() ); Ok(()) }) .unwrap(); }) } fn cannot_rebox_as_incompatible() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "DoubleVariant")? .as_managed() .cast::()?; let v2 = Value::new(&mut frame, 2i16); let jl_val = constr .instantiate(&mut frame, &mut [v2])? .into_jlrs_result()?; let unboxed = jl_val.unbox::()?; assert!( Value::try_new_with::(&mut frame, unboxed).is_err() ); Ok(()) }) .unwrap(); }) } fn derive_generic_tu() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let ty = WithGenericTU::::construct_type(&mut frame); assert_eq!( ty.cast::().unwrap().size().unwrap() as usize, std::mem::size_of::() + std::mem::size_of::() ); Ok(()) }) .unwrap(); }) } fn derive_bits_type_char() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeChar { a: Char::new('b') }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap().try_as_char().unwrap(), 'b'); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_uint8() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeUInt8 { a: 1 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), 1); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_uint16() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeUInt16 { a: 2 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), 2); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_uint32() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeUInt32 { a: 3 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), 3); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_uint64() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeUInt64 { a: 4 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), 4); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_uint() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeUInt { a: 5 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), 5); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_int8() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeInt8 { a: -1 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), -1); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_int16() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeInt16 { a: -2 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), -2); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_int32() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeInt32 { a: -3 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), -3); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_int64() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeInt64 { a: -4 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), -4); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_int() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeInt { a: -5 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), -5); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_float32() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeFloat32 { a: 1.2 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), 1.2); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_type_float64() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsTypeFloat64 { a: -2.3 }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), -2.3); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_char_float32_float64() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsCharFloat32Float64 { a: Char::new('a'), b: 3.0, c: 4.0, }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap().try_as_char().unwrap(), 'a'); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_int_bool() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsIntBool { a: 1, b: Bool::new(true), }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), 1); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_char_bits_int_char() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsCharBitsIntChar { a: Char::new('a'), b: BitsIntChar { a: 1, b: Char::new('b'), }, }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap().try_as_char().unwrap(), 'a'); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_uint8_tuple_int32_int64() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let s = BitsUInt8TupleInt32Int64 { a: 0, b: Tuple2(-1, -3), }; let v = Value::new(&mut frame, s); let first = v.get_nth_field(&mut frame, 0).unwrap(); let second = v.get_nth_field(&mut frame, 1).unwrap(); assert_eq!(first.unbox::().unwrap(), 0); assert_eq!(second.unbox::>().unwrap(), Tuple2(-1, -3)); assert!(v.is::()); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_bits_uint8_tuple_int32_tuple_int16_uint16() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let rs_val = BitsUInt8TupleInt32TupleInt16UInt16 { a: 0, b: Tuple2(-1, Tuple2(-1, 3)), }; let jl_val = Value::new(&mut frame, rs_val.clone()); unsafe { assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); } let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), (&rs_val).a); let second = jl_val.get_nth_field(&mut frame, 1).unwrap(); assert_eq!( second.unbox::>>().unwrap(), rs_val.b ); assert!(jl_val.is::()); assert!(jl_val .unbox::() .is_ok()); Ok(()) }) .unwrap(); }) } fn derive_single_variant() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "SingleVariant")? .as_managed(); let v2 = Value::new(&mut frame, 2i32); let jl_val = constr.call1(&mut frame, v2).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_size_align_mismatch() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "SizeAlignMismatch")? .as_managed(); let v2 = Value::new(&mut frame, 2i32); let jl_val = constr.call1(&mut frame, v2).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); let second = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(second.unbox::().unwrap(), 2); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_union_in_tuple() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "UnionInTuple")? .as_managed(); let v2 = Value::new(&mut frame, Tuple1(2i32)); let jl_val = constr.call1(&mut frame, v2).unwrap(); let second = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(second.unbox::>().unwrap(), Tuple1(2)); let _uit = jl_val.unbox::()?; Ok(()) }) .unwrap(); }) } fn derive_non_bits_union() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "NonBitsUnion")? .as_managed(); let v1 = Value::new(&mut frame, 1i8); let jl_val = constr.call1(&mut frame, v1).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), 1); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_string() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "WithString")? .as_managed(); let s = JuliaString::new(&mut frame, "foo"); let jl_val = constr.call1(&mut frame, s.as_value()).into_jlrs_result()?; assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .into_jlrs_result()? .cast::()? .is::()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap().unwrap(), "foo"); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_with_generic_t_i32() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "WithGenericT")? .as_managed(); let v1 = Value::new(&mut frame, 1i32); let jl_val = constr.call1(&mut frame, v1).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::>()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert_eq!(first.unbox::().unwrap(), 1); assert!(jl_val.is::>()); assert!(jl_val.unbox::>().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_with_unionall() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "WithGenericT")? .as_managed(); let v1 = Value::new(&mut frame, 1i32); let wgt = constr.call1(&mut frame, v1).unwrap(); let constr = Module::main(&frame) .global(&frame, "WithGenericUnionAll")? .as_managed(); let jl_val = constr.call1(&mut frame, wgt).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert!(first.unbox::>().is_ok()); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_with_nested_generic() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let constr = Module::main(&frame) .global(&frame, "WithGenericT")? .as_managed(); let v1 = Value::new(&mut frame, 1i32); let wgt = constr.call1(&mut frame, v1).unwrap(); let constr = Module::main(&frame) .global(&frame, "WithNestedGenericT")? .as_managed(); let jl_val = constr.call1(&mut frame, wgt).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::>()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert!(first.unbox::>().is_ok()); assert!(jl_val.is::>()); assert!(jl_val.unbox::>().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_with_propagated_lifetime() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let global = frame.unrooted(); let constr = Module::main(&frame) .global(&frame, "WithGenericT")? .as_managed(); let wgt = constr .call1(&mut frame, Module::base(&global).as_value()) .unwrap(); let constr = Module::main(&frame) .global(&frame, "WithPropagatedLifetime")? .as_managed(); let jl_val = constr.call1(&mut frame, wgt).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert!(first.unbox::>>().is_ok()); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_with_propagated_lifetimes() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let arr = TypedArray::::new(&mut frame, (2, 2)).into_jlrs_result()?; let wgt_constr = Module::main(&frame) .global(&frame, "WithGenericT")? .as_managed(); let wgt = wgt_constr.call1(&mut frame, arr.as_value()).unwrap(); let constr = Module::base(&frame).function(&frame, "tuple")?.as_managed(); let int = Value::new(&mut frame, 2i32); let tup = constr.call2(&mut frame, int, wgt).unwrap(); let a = wgt_constr.call1(&mut frame, tup).unwrap(); let constr = Module::main(&frame) .global(&frame, "WithPropagatedLifetimes")? .as_managed(); let jl_val = constr.call1(&mut frame, a).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert!(first .unbox::>>>>() .is_ok()); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_with_set_generic() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let wgt_constr = Module::main(&frame) .global(&frame, "WithGenericT")? .as_managed(); let v1 = Value::new(&mut frame, 1i64); let wgt = wgt_constr.call1(&mut frame, v1).unwrap(); let constr = Module::main(&frame) .global(&frame, "WithSetGeneric")? .as_managed(); let jl_val = constr.call1(&mut frame, wgt).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert!(first.unbox::>().is_ok()); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_with_set_generic_tuple() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let wgt_constr = Module::main(&frame) .global(&frame, "WithGenericT")? .as_managed(); let v1 = Value::new(&mut frame, 1i64); let wgt = wgt_constr.call1(&mut frame, v1).unwrap(); let tup_constr = Module::base(&frame).function(&frame, "tuple")?.as_managed(); let v2 = tup_constr.call1(&mut frame, wgt).unwrap(); let constr = Module::main(&frame) .global(&frame, "WithSetGenericTuple")? .as_managed(); let jl_val = constr.call1(&mut frame, v2).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); first.unbox::>>().unwrap(); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_with_value_type() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| unsafe { let b = Value::new(&mut frame, true); let wvt_constr = Module::main(&frame) .global(&frame, "WithValueType")? .as_managed() .apply_type(&mut frame, [b]) .into_jlrs_result()?; let v1 = Value::new(&mut frame, 1i64); let jl_val = wvt_constr.call1(&mut frame, v1).unwrap(); assert!(Module::base(&frame) .function(&frame, "typeof")? .as_managed() .call1(&mut frame, jl_val) .unwrap() .cast::()? .is::()); let first = jl_val.get_nth_field(&mut frame, 0).unwrap(); assert!(first.unbox::().is_ok()); assert!(jl_val.is::()); assert!(jl_val.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn derive_zero_sized() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let v = Value::new(&mut frame, Empty {}); assert!(v.unbox::().is_ok()); Ok(()) }) .unwrap(); }) } fn isbits_into_julia() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let wvt = WithValueType { a: 1 }; type WVT = WithValueTypeTypeConstructor>; let v = Value::new_bits_from_layout::(&mut frame, wvt.clone())?; let wvt_unboxed = v.unbox::()?; assert_eq!(wvt, wvt_unboxed); Ok(()) }) .unwrap(); }) } fn trivial_isbits_into_julia() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { let layout = WithGenericTU { a: 1i32, b: 2u32 }; let v = Value::new_bits(&mut frame, layout.clone()); let layout_unboxed = v.unbox::>()?; assert_eq!(layout, layout_unboxed); Ok(()) }) .unwrap(); }) } fn test_enums() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { // Test IntoJulia, Typecheck, ValidLayout, ValidField and Unbox for each variant. let mut test_fn = |layout| -> JlrsResult<_> { let v = Value::new(&mut frame, layout); assert!(v.is::()); assert!(StandardEnum::valid_layout(v.datatype().as_value())); assert!(StandardEnum::valid_field(v.datatype().as_value())); let layout_unboxed = v.unbox::()?; assert_eq!(layout, layout_unboxed); Ok(()) }; test_fn(StandardEnum::SeA)?; test_fn(StandardEnum::SeB)?; test_fn(StandardEnum::SeC)?; Ok(()) }) .unwrap(); }) } fn test_enums_ccall() { JULIA_DERIVE.with(|j| { let mut julia = j.borrow_mut(); let mut frame = StackFrame::new(); julia .instance(&mut frame) .returning::>() .scope(|mut frame| { // Test that enums can be passed and returned by value unsafe extern "C" fn echo(s: StandardEnum) -> StandardEnum { s } let echo_v = Value::new(&mut frame, echo as *mut c_void); let se_a = StandardEnum::SeA.as_value(&frame); let func = unsafe { Value::eval_string( &mut frame, "x(f, s::StandardEnum) = ccall(f, StandardEnum, (StandardEnum,), s)", ) } .unwrap(); let res = unsafe { func.call2(&mut frame, echo_v, se_a) }.unwrap(); assert_eq!(se_a, res); Ok(()) }) .unwrap(); }) } #[test] fn derive_tests() { derive_bits_type_bool(); derive_elided(); derive_elided_with_ptr(); derive_double_variant(); rebox_double_variant(); cannot_rebox_as_incompatible(); derive_generic_tu(); derive_bits_type_char(); derive_bits_type_uint8(); derive_bits_type_uint16(); derive_bits_type_uint32(); derive_bits_type_uint64(); derive_bits_type_uint(); derive_bits_type_int8(); derive_bits_type_int16(); derive_bits_type_int32(); derive_bits_type_int64(); derive_bits_type_int(); derive_bits_type_float32(); derive_bits_type_float64(); derive_bits_char_float32_float64(); derive_bits_int_bool(); derive_bits_char_bits_int_char(); derive_bits_uint8_tuple_int32_int64(); derive_bits_uint8_tuple_int32_tuple_int16_uint16(); derive_single_variant(); derive_size_align_mismatch(); derive_union_in_tuple(); derive_non_bits_union(); derive_with_generic_t_i32(); derive_with_unionall(); derive_with_nested_generic(); derive_with_propagated_lifetime(); derive_with_set_generic(); derive_with_set_generic_tuple(); derive_with_value_type(); derive_zero_sized(); derive_with_propagated_lifetimes(); derive_string(); isbits_into_julia(); trivial_isbits_into_julia(); test_enums(); test_enums_ccall(); } }