koto_random 0.16.1

A Koto library for working with random numbers
Documentation
use koto_derive::*;
use koto_runtime::{Result, prelude::*};
use koto_test_utils::*;
use std::{error::Error, fs, path::PathBuf, result::Result as StdResult};

#[derive(Clone, Debug, Default, KotoCopy, KotoType)]
struct TestContainer {
    data: Vec<KValue>,
}

#[koto_impl(runtime = koto_runtime)]
impl TestContainer {
    #[koto_method]
    fn push(&mut self, args: &[KValue]) {
        self.data.extend_from_slice(args);
    }

    #[koto_method]
    fn to_tuple(&self) -> KValue {
        KTuple::from(self.data.clone()).into()
    }
}

impl KotoObject for TestContainer {
    fn size(&self) -> Option<usize> {
        Some(self.data.len())
    }

    fn index(&self, index: &KValue) -> Result<KValue> {
        match index {
            KValue::Number(i) => Ok(self.data[usize::from(i)].clone()),
            unexpected => unexpected_type("An index", unexpected),
        }
    }

    fn index_mut(&mut self, index: &KValue, value: &KValue) -> Result<()> {
        match index {
            KValue::Number(i) => {
                self.data[usize::from(i)] = value.clone();
                Ok(())
            }
            unexpected => unexpected_type("An index", unexpected),
        }
    }
}

#[test]
fn shuffle() -> StdResult<(), Box<dyn Error>> {
    let vm = KotoVm::default();
    let prelude = vm.prelude();

    prelude.insert("random", koto_random::make_module());

    prelude.add_fn("new_container", |ctx| {
        let data: Vec<KValue> = ctx.args().to_vec();
        Ok(KObject::from(TestContainer { data }).into())
    });

    let script_path = PathBuf::from_iter(&[env!("CARGO_MANIFEST_DIR"), "tests", "shuffle.koto"]);
    let script = fs::read_to_string(&script_path)?;

    run_test_script(vm, &script, Some(script_path.into()), None)?;

    Ok(())
}