intuicio-core 0.20.5

Core module for Intuicio scripting platform
Documentation
use crate::{
    function::{Function, FunctionHandle, FunctionQuery},
    prelude::{NativeStructBuilder, StructQuery},
    struct_type::{Struct, StructHandle},
};
use std::sync::Arc;

pub type RegistryHandle = Arc<Registry>;

#[derive(Debug, Default, Clone)]
pub struct Registry {
    functions: Vec<FunctionHandle>,
    structs: Vec<StructHandle>,
}

impl Registry {
    pub fn with_basic_types(self) -> Self {
        self.with_struct(NativeStructBuilder::new::<()>().build())
            .with_struct(NativeStructBuilder::new::<bool>().build())
            .with_struct(NativeStructBuilder::new::<i8>().build())
            .with_struct(NativeStructBuilder::new::<i16>().build())
            .with_struct(NativeStructBuilder::new::<i32>().build())
            .with_struct(NativeStructBuilder::new::<i64>().build())
            .with_struct(NativeStructBuilder::new::<i128>().build())
            .with_struct(NativeStructBuilder::new::<isize>().build())
            .with_struct(NativeStructBuilder::new::<u8>().build())
            .with_struct(NativeStructBuilder::new::<u16>().build())
            .with_struct(NativeStructBuilder::new::<u32>().build())
            .with_struct(NativeStructBuilder::new::<u64>().build())
            .with_struct(NativeStructBuilder::new::<u128>().build())
            .with_struct(NativeStructBuilder::new::<usize>().build())
            .with_struct(NativeStructBuilder::new::<f32>().build())
            .with_struct(NativeStructBuilder::new::<f64>().build())
            .with_struct(NativeStructBuilder::new::<char>().build())
            .with_struct(NativeStructBuilder::new_named::<String>("String").build())
    }

    pub fn with_function(mut self, function: Function) -> Self {
        self.add_function(function);
        self
    }

    pub fn with_struct(mut self, struct_type: Struct) -> Self {
        self.add_struct(struct_type);
        self
    }

    pub fn add_function_handle(&mut self, function_handle: FunctionHandle) {
        if !self
            .functions
            .iter()
            .any(|handle| handle.signature() == function_handle.signature())
        {
            self.functions.push(function_handle);
        }
    }

    pub fn add_function(&mut self, function: Function) -> FunctionHandle {
        if let Some(handle) = self
            .functions
            .iter()
            .find(|handle| handle.signature() == function.signature())
        {
            handle.clone()
        } else {
            let handle = FunctionHandle::new(function);
            self.functions.push(handle.clone());
            handle
        }
    }

    pub fn remove_function(&mut self, function_handle: FunctionHandle) {
        if let Some(position) = self
            .functions
            .iter()
            .position(|handle| handle.signature() == function_handle.signature())
        {
            self.functions.remove(position);
        }
    }

    pub fn remove_functions(&mut self, query: FunctionQuery) {
        while let Some(position) = self
            .functions
            .iter()
            .position(|handle| query.is_valid(handle.signature()))
        {
            self.functions.swap_remove(position);
        }
    }

    pub fn functions(&self) -> impl Iterator<Item = &FunctionHandle> {
        self.functions.iter()
    }

    pub fn find_functions<'a>(
        &'a self,
        query: FunctionQuery<'a>,
    ) -> impl Iterator<Item = FunctionHandle> + '_ {
        self.functions
            .iter()
            .filter(move |handle| query.is_valid(handle.signature()))
            .cloned()
    }

    pub fn find_function<'a>(&'a self, query: FunctionQuery<'a>) -> Option<FunctionHandle> {
        self.find_functions(query).next()
    }

    pub fn add_struct_handle(&mut self, struct_handle: StructHandle) {
        if !self
            .structs
            .iter()
            .any(|handle| handle.as_ref() == struct_handle.as_ref())
        {
            self.structs.push(struct_handle);
        }
    }

    pub fn add_struct(&mut self, struct_type: Struct) -> StructHandle {
        if let Some(handle) = self
            .structs
            .iter()
            .find(|handle| handle.as_ref() == &struct_type)
        {
            handle.clone()
        } else {
            let handle = StructHandle::new(struct_type);
            self.structs.push(handle.clone());
            handle
        }
    }

    pub fn remove_struct(&mut self, struct_handle: StructHandle) {
        if let Some(position) = self
            .structs
            .iter()
            .position(|handle| handle == &struct_handle)
        {
            self.functions.remove(position);
        }
    }

    pub fn remove_structs(&mut self, query: StructQuery) {
        while let Some(position) = self
            .structs
            .iter()
            .position(|handle| query.is_valid(handle))
        {
            self.structs.swap_remove(position);
        }
    }

    pub fn structs(&self) -> impl Iterator<Item = &StructHandle> {
        self.structs.iter()
    }

    pub fn find_structs<'a>(
        &'a self,
        query: StructQuery<'a>,
    ) -> impl Iterator<Item = StructHandle> + '_ {
        self.structs
            .iter()
            .filter(move |handle| query.is_valid(handle))
            .cloned()
    }

    pub fn find_struct<'a>(&'a self, query: StructQuery<'a>) -> Option<StructHandle> {
        self.find_structs(query).next()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_async() {
        fn is_async<T: Send + Sync>() {}

        is_async::<Registry>();
    }
}