1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
//! # Anonymous Function with multi-arity
//!
//! This is a map of

// use lazy_static::{__Deref, lazy_static};
use std::sync::*;

use clojure::rust::*;
// use clojure::lang::*;
use intertrait::*;

use crate::*;
castable_to!(SFunction => [sync] IObject, Function);

pub struct SFunction {
    /// index of full name: ns + class/protocol + name
    pub full_name: usize,
    /// Mark optional arity of multi-arity function.
    pub multiary:  Option<usize>,
    /// PersistentHashMap arity `usize` ->
    pub func:      Object,
}

unsafe impl Send for SFunction {}

unsafe impl Sync for SFunction {}

pub trait Function: IObject+CastFromSync {
    fn call(
        &self,
        args: &Object,
    ) -> ObjResult<Object>;

    fn get(
        &self,
        arity: usize,
    ) -> ObjResult<Object>;
}

impl Function for SFunction {
    fn get(
        &self,
        arity: usize,
    ) -> ObjResult<Object> {
        // let mut index = arity;
        // match self.multiary {
        //     Some(max) => {
        //         if arity > max {
        //             index = max;
        //         }
        //         let implem = Object::cast::<SFunction>(&self.func);
        //         let funcs = implem.get(index);
        //         let a = Object::cast::<SFnMethodNative>(&implem);
        //         let fn_nat = Object::cast::<SFnMethodNative>(a);
        //         Object::null()
        //     },
        //     // If no max => no implementation
        //     None => todo!(),
        // }
        todo!()
    }

    fn call(
        &self,
        args: &Object,
    ) -> ObjResult<Object> {
        todo!()
    }
}

impl IObject for SFunction {
    fn getClass<'a>(&self) -> &'a SClass { todo!() }

    fn hashCode(&self) -> usize { todo!() }

    fn equals(
        &self,
        other: &Object,
    ) -> bool {
        todo!()
    }

    fn toString(&self) -> String { todo!() }
}

use crate::new_obj;

impl SFunction {
    pub fn new(
        full_name: usize,
        multiary: Option<usize>,
        func: Object,
    ) -> Object {
        new_obj!(SFunction {
            full_name,
            multiary,
            func
        })
    }
}

impl Default for SFunction {
    fn default() -> Self { todo!() }
}