jlrs 0.23.0

jlrs provides bindings to the Julia C API that enable Julia code to be called from Rust and more.
Documentation
mod util;

#[cfg(feature = "local-rt")]
mod tests {
    use jlrs::{
        data::{
            layout::valid_layout::ValidLayout,
            managed::{
                simple_vector::{SimpleVector, WeakSimpleVector},
                union_all::UnionAll,
            },
        },
        prelude::*,
    };

    use crate::util::JULIA;

    fn create_simple_vector() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let svec = SimpleVector::with_capacity(&mut frame, 1);
                    assert!(svec.as_value().is::<SimpleVector>());
                })
            })
        })
    }

    fn set_simple_vector_contents() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let svec = unsafe { SimpleVector::with_capacity_uninit(&mut frame, 1) };
                    let value = Value::new(&mut frame, 1usize);

                    unsafe {
                        let data = svec.data();
                        assert!(data.set(0, Some(value)).is_ok());
                    }
                })
            })
        })
    }

    fn set_simple_vector_contents_unrestricted() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let svec = unsafe { SimpleVector::with_capacity_uninit(&mut frame, 1) };
                    let value = Value::new(&mut frame, 1usize);

                    unsafe {
                        let data = svec.data();
                        assert!(data.set(0, Some(value)).is_ok());
                    }
                })
            })
        })
    }

    fn typed_simple_vector_contents() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let svec = unsafe { SimpleVector::with_capacity_uninit(&mut frame, 1) };
                    let sym = Symbol::new(&frame, "Foo");

                    unsafe {
                        let data = svec.data();
                        assert!(data.set(0, Some(sym.as_value())).is_ok());
                    }

                    unsafe {
                        let data = svec.typed_data_unchecked::<Symbol>();
                        assert_eq!(data.as_atomic_slice().assume_immutable_non_null()[0], sym);
                    }
                })
            })
        })
    }

    fn set_simple_vector_contents_oob() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let svec = unsafe { SimpleVector::with_capacity_uninit(&mut frame, 1) };
                    let value = Value::new(&mut frame, 1usize);

                    unsafe {
                        let data = svec.data();
                        assert!(data.set(1, Some(value)).is_err());
                    }
                })
            })
        })
    }

    fn set_simple_vector_contents_unrestricted_oob() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let svec = unsafe { SimpleVector::with_capacity_uninit(&mut frame, 1) };
                    let value = Value::new(&mut frame, 1usize);

                    unsafe {
                        let data = svec.data();
                        assert!(data.set(1, Some(value)).is_err());
                    }
                })
            })
        })
    }

    fn extend_lifetime() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let output = frame.output();
                    frame.scope(|mut frame| {
                        let svec = SimpleVector::with_capacity(&mut frame, 0).clone();
                        svec.root(output)
                    });
                });
            })
        })
    }

    fn empty() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let svec = SimpleVector::with_capacity(&mut frame, 0);
                    assert_eq!(svec.as_value(), SimpleVector::emptysvec(&frame));
                });
            })
        })
    }

    fn root_ref() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let res = unsafe { SimpleVector::emptysvec(&frame).as_weak().root(&mut frame) };
                    assert_eq!(res.len(), 0);
                })
            })
        })
    }

    fn valid_layout() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|frame| {
                    let res = SimpleVector::emptysvec(&frame);
                    assert!(res.as_value().is::<SimpleVector>());
                    assert!(WeakSimpleVector::valid_layout(
                        res.as_value().datatype().as_value()
                    ));

                    let value = DataType::unionall_type(&frame).as_value();
                    assert!(!value.is::<SimpleVector>());
                    assert!(!WeakSimpleVector::valid_layout(
                        UnionAll::array_type(&frame).as_value()
                    ));
                })
            })
        })
    }

    fn debug_fmt() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|frame| {
                    let res = SimpleVector::emptysvec(&frame);
                    let fmt = format!("{:?}", res);
                    assert_eq!(fmt, "svec()");
                })
            })
        })
    }

    #[test]
    fn simple_vector_tests() {
        create_simple_vector();
        set_simple_vector_contents();
        set_simple_vector_contents_unrestricted();
        typed_simple_vector_contents();
        set_simple_vector_contents_oob();
        set_simple_vector_contents_unrestricted_oob();
        extend_lifetime();
        empty();
        root_ref();
        valid_layout();
        debug_fmt();
    }
}