acts 0.17.2

a fast, lightweight, extensiable workflow engine
Documentation
use super::super::ActModule;
use crate::{ActError, Result};
use rquickjs::{CatchResultExt, Module as JsModule};

#[derive(Clone)]
pub struct ArrayModule {}

#[allow(clippy::module_inception)]
#[rquickjs::module(rename_vars = "camelCase")]
mod array {
    use std::collections::BTreeSet;

    #[rquickjs::function]
    pub fn intersection(a: Vec<String>, b: Vec<String>) -> Vec<String> {
        let mut set_a = BTreeSet::new();
        let mut set_b = BTreeSet::new();
        for v in a.iter() {
            set_a.insert(v);
        }

        for v in b.iter() {
            set_b.insert(v);
        }

        set_a
            .intersection(&set_b)
            .map(|i| i.to_string())
            .collect::<Vec<_>>()
    }

    #[rquickjs::function]
    pub fn union(a: Vec<String>, b: Vec<String>) -> Vec<String> {
        let mut set_a = BTreeSet::new();
        let mut set_b = BTreeSet::new();
        for v in a.iter() {
            set_a.insert(v);
        }

        for v in b.iter() {
            set_b.insert(v);
        }

        set_a
            .union(&set_b)
            .map(|i| i.to_string())
            .collect::<Vec<_>>()
    }

    #[rquickjs::function]
    pub fn difference(a: Vec<String>, b: Vec<String>) -> Vec<String> {
        let mut set_a = BTreeSet::new();
        let mut set_b = BTreeSet::new();

        for v in a.iter() {
            set_a.insert(v);
        }

        for v in b.iter() {
            set_b.insert(v);
        }
        set_a
            .difference(&set_b)
            .map(|i| i.to_string())
            .collect::<Vec<_>>()
    }
}

impl ArrayModule {
    pub fn new() -> Self {
        Self {}
    }
}

impl ActModule for ArrayModule {
    fn init(&self, ctx: &rquickjs::Ctx<'_>) -> Result<()> {
        JsModule::declare_def::<js_array, _>(ctx.clone(), "@acts/array").unwrap();

        let source = r#"
        import { intersection, union, difference } from '@acts/array';
        Array.prototype.intersection = function(b){
            return intersection(this, b);
        }

        Array.prototype.union = function(b){
            return union(this, b);
        }

        Array.prototype.difference = function(b){
            return difference(this, b);
        }
        "#;

        let _ = JsModule::evaluate(ctx.clone(), "@acts/array", source)
            .catch(ctx)
            .map_err(|err| ActError::Script(err.to_string()))?;
        Ok(())
    }
}