jlrs 0.23.0

jlrs provides bindings to the Julia C API that enable Julia code to be called from Rust and more.
Documentation
#[cfg(feature = "local-rt")]
pub(crate) mod tests {
    use jlrs::prelude::*;

    use crate::util::JULIA;

    fn array_new_for() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let arr = Array::new_for(&mut frame, dt, [1, 2]);
                    assert!(arr.is_ok());

                    let arr = arr.unwrap();
                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    fn array_new_for_unchecked() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let arr = unsafe { Array::new_for_unchecked(&mut frame, dt, [1, 2]) };
                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    fn array_from_slice_for() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = Array::from_slice_for(&mut frame, dt, data, [1, 2]);
                    assert!(arr.is_ok());
                    let arr = arr.unwrap();
                    assert!(arr.is_ok());
                    let arr = arr.unwrap();

                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    fn array_from_slice_for_type_err() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float64_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = Array::from_slice_for(&mut frame, dt, data, [1, 2]);
                    assert!(arr.is_err());
                })
            });
        });
    }

    fn array_from_slice_for_size_err() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = Array::from_slice_for(&mut frame, dt, data, [2, 2]);
                    assert!(arr.is_err());
                })
            });
        });
    }

    fn array_from_slice_for_unchecked() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr =
                        unsafe { Array::from_slice_for_unchecked(&mut frame, dt, data, [1, 2]) };

                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    fn array_from_vec_for() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let data = vec![1f32, 2f32];
                    let arr = Array::from_vec_for(&mut frame, dt, data, [1, 2]);
                    assert!(arr.is_ok());
                    let arr = arr.unwrap();
                    assert!(arr.is_ok());
                    let arr = arr.unwrap();

                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    fn array_from_vec_for_type_err() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float64_type(&frame).as_value();
                    let data = vec![1f32, 2f32];
                    let arr = Array::from_vec_for(&mut frame, dt, data, [1, 2]);
                    assert!(arr.is_err());
                })
            });
        });
    }

    fn array_from_vec_for_size_err() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let data = vec![1f32, 2f32];
                    let arr = Array::from_vec_for(&mut frame, dt, data, [2, 2]);
                    assert!(arr.is_err());
                })
            });
        });
    }

    fn array_from_vec_for_unchecked() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let data = vec![1f32, 2f32];
                    let arr =
                        unsafe { Array::from_vec_for_unchecked(&mut frame, dt, data, [1, 2]) };

                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    fn array_from_slice_cloned_for() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = Array::from_slice_cloned_for(&mut frame, dt, data, [1, 2]);
                    assert!(arr.is_ok());
                    let arr = arr.unwrap();
                    assert!(arr.is_ok());
                    let arr = arr.unwrap();

                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    fn array_from_slice_cloned_for_type_err() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float64_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = Array::from_slice_cloned_for(&mut frame, dt, data, [1, 2]);
                    assert!(arr.is_err());
                })
            });
        });
    }

    fn array_from_slice_cloned_for_size_err() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = Array::from_slice_cloned_for(&mut frame, dt, data, [2, 2]);
                    assert!(arr.is_err());
                })
            });
        });
    }

    fn array_from_slice_cloned_for_unchecked() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = unsafe {
                        Array::from_slice_cloned_for_unchecked(&mut frame, dt, data, [1, 2])
                    };

                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    fn array_from_slice_copied_for() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = Array::from_slice_copied_for(&mut frame, dt, data, [1, 2]);
                    assert!(arr.is_ok());
                    let arr = arr.unwrap();
                    assert!(arr.is_ok());
                    let arr = arr.unwrap();

                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    fn array_from_slice_copied_for_type_err() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float64_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = Array::from_slice_copied_for(&mut frame, dt, data, [1, 2]);
                    assert!(arr.is_err());
                })
            });
        });
    }

    fn array_from_slice_copied_for_size_err() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = Array::from_slice_copied_for(&mut frame, dt, data, [2, 2]);
                    assert!(arr.is_err());
                })
            });
        });
    }

    fn array_from_slice_copied_for_unchecked() {
        JULIA.with(|handle| {
            handle.borrow_mut().with_stack(|mut stack| {
                stack.scope(|mut frame| {
                    let dt = DataType::float32_type(&frame).as_value();
                    let mut data = vec![1f32, 2f32];
                    let data = data.as_mut_slice();
                    let arr = unsafe {
                        Array::from_slice_copied_for_unchecked(&mut frame, dt, data, [1, 2])
                    };

                    assert_eq!(arr.n_dims(), 2);
                    assert_eq!(arr.element_type(), dt);
                })
            });
        });
    }

    // TODO: Test 1D, 2D, 3D, and 4D cases to cover all ctors
    // TODO: Test that exception is thrown if the number of elements >= isize::MAX
    pub(crate) fn array_constructor_tests() {
        array_new_for();
        array_new_for_unchecked();

        array_from_slice_for();
        array_from_slice_for_size_err();
        array_from_slice_for_type_err();
        array_from_slice_for_unchecked();

        array_from_vec_for();
        array_from_vec_for_size_err();
        array_from_vec_for_type_err();
        array_from_vec_for_unchecked();

        array_from_slice_cloned_for();
        array_from_slice_cloned_for_size_err();
        array_from_slice_cloned_for_type_err();
        array_from_slice_cloned_for_unchecked();

        array_from_slice_copied_for();
        array_from_slice_copied_for_size_err();
        array_from_slice_copied_for_type_err();
        array_from_slice_copied_for_unchecked();
    }
}