rush_core/
function.rs

1use crate::{Function, FunctionSet};
2use anyhow::anyhow;
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use std::sync::Arc;
6use wd_tools::{PFErr, PFOk};
7
8pub trait FromValue: Sized {
9    fn from(val: Value) -> anyhow::Result<Self>;
10}
11// impl FromValue for String{
12//     fn from(value: Value)->anyhow::Result<Self>{
13//         if let Value::String(s) = value{
14//             return  s.ok()
15//         }
16//         return anyhow!("unknown type[{}] FromValue for String",value).err()
17//     }
18// }
19// macro_rules! from_value_i64 {
20//     ($($t:ty),*) => {
21//         $(
22//         impl FromValue for $t{
23//             fn from(val: Value) -> anyhow::Result<Self> {
24//             if let Value::Number(ref n) = val{
25//                 if let Some(i) = n.as_i64(){
26//                     return (i as $t).ok()
27//                 }
28//             }
29//             return anyhow!("unknown type[{}] FromValue for number",val).err()
30//             }
31//         }
32//         )*
33//     };
34// }
35// from_value_i64!(i8,i16,i32,i64,isize,u8,u16,u32,u64,usize);
36//
37// macro_rules! from_value_f64 {
38//     ($($t:ty),*) => {
39//         $(
40// impl FromValue for $t{
41//     fn from(val: Value) -> anyhow::Result<Self> {
42//     if let Value::Number(ref n) = val{
43//         if let Some(f) = n.as_f64(){
44//             return (f as $t).ok()
45//         }
46//     }
47//     return anyhow!("unknown type[{}] FromValue for float",val).err()
48// }
49// }
50//         )*
51//     };
52// }
53// from_value_f64!(f32,f64);
54//
55// impl FromValue for bool{
56//     fn from(val: Value) -> anyhow::Result<Self> {
57//         if let Value::Bool(b) = val{
58//             return b.ok()
59//         }
60//         return anyhow!("unknown type[{}] FromValue for bool",val).err()
61//     }
62// }
63// impl FromValue for Option<()>{
64//     fn from(val: Value) -> anyhow::Result<Self> {
65//         if let Value::Null = val{
66//             return None.ok()
67//         }
68//         return anyhow!("unknown type[{}] FromValue for null",val).err()
69//     }
70// }
71//
72// impl<T:FromValue> FromValue for Vec<T>{
73//     fn from(val: Value) -> anyhow::Result<Self> {
74//         if let Value::Array(array) = val{
75//             let mut list = vec![];
76//             for i in array{
77//                 list.push(T::from(i)?);
78//             }
79//             return list.ok()
80//         }
81//         return anyhow!("unknown type[{}] FromValue for array",val).err()
82//     }
83// }
84impl<T> FromValue for T
85where
86    T: for<'a> Deserialize<'a>,
87{
88    fn from(val: Value) -> anyhow::Result<Self> {
89        let t: T = serde_json::from_value(val)?;
90        t.ok()
91    }
92}
93
94pub trait HostFunction<A, O>: Send + Sync {
95    fn call(&self, args: Vec<Value>) -> anyhow::Result<Value>;
96}
97pub struct FunctionImpl<A, O> {
98    inner: Box<dyn HostFunction<A, O>>,
99}
100
101impl<A, O> FunctionImpl<A, O> {
102    pub fn new<F: HostFunction<A, O> + Send + Sync + 'static>(f: F) -> Self {
103        let inner = Box::new(f);
104        Self { inner }
105    }
106}
107
108impl<A, O> Function for FunctionImpl<A, O>
109where
110    O: Serialize,
111{
112    fn call(&self, _fs: Arc<dyn FunctionSet>, args: Vec<Value>) -> anyhow::Result<Value> {
113        self.inner.call(args)
114    }
115}
116impl<O, F> HostFunction<(), O> for F
117where
118    O: Serialize,
119    F: Fn() -> anyhow::Result<O> + Send + Sync + 'static,
120{
121    fn call(&self, _args: Vec<Value>) -> anyhow::Result<Value> {
122        let out = self()?;
123        let val = serde_json::to_value(out)?;
124        Ok(val)
125    }
126}
127macro_rules! function_impl_template {
128    ($n:tt,$($t:tt),*) => {
129        impl<$($t,)* O,F> HostFunction<($($t,)*),O> for F
130where $($t:FromValue,)*
131        O:Serialize,F:Fn($($t,)*)->anyhow::Result<O> + Send + Sync + 'static
132{
133    fn call(&self, mut args: Vec<Value>) -> anyhow::Result<Value> {
134        if args.len() < $n {
135            return anyhow!("expecting {} parameters actually finds {} parameters",$n,args.len()).err()
136        }
137        let out = self($($t::from(args.remove(0))?,)*)?;
138        let val = serde_json::to_value(out)?;
139        Ok(val)
140    }
141}
142    };
143}
144function_impl_template!(1, A1);
145function_impl_template!(2, A1, A2);
146function_impl_template!(3, A1, A2, A3);
147function_impl_template!(4, A1, A2, A3, A4);
148function_impl_template!(5, A1, A2, A3, A4, A5);
149function_impl_template!(6, A1, A2, A3, A4, A5, A6);
150function_impl_template!(7, A1, A2, A3, A4, A5, A6, A7);
151function_impl_template!(8, A1, A2, A3, A4, A5, A6, A7, A8);
152function_impl_template!(9, A1, A2, A3, A4, A5, A6, A7, A8, A9);
153function_impl_template!(10, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
154function_impl_template!(11, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11);
155function_impl_template!(12, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12);
156function_impl_template!(13, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13);
157function_impl_template!(14, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14);
158function_impl_template!(15, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15);
159function_impl_template!(16, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16);
160
161#[cfg(test)]
162mod test {
163    use crate::{Function, FunctionImpl, FunctionSet, HostFunction};
164    use serde::Serialize;
165    use serde_json::Value;
166    use std::sync::Arc;
167    #[derive(Debug)]
168    struct FSet;
169    impl FunctionSet for FSet {
170        fn get(&self, _name: &str) -> Option<Arc<dyn Function>> {
171            None
172        }
173    }
174
175    fn call<A, O: Serialize, F: HostFunction<A, O> + 'static>(f: F) {
176        let f = FunctionImpl { inner: Box::new(f) };
177        let b: Box<dyn Function> = Box::new(f);
178        let _ = b
179            .call(
180                Arc::new(FSet {}),
181                vec![Value::String("hello".into()), Value::String("world".into())],
182            )
183            .unwrap();
184        // let _ =  f.call(Arc::new(FSet{}),vec![Value::String("hello".into()),Value::String("world".into())]);
185    }
186
187    //cargo test --color=always --lib function::test::test_fn --no-fail-fast -- --exact unstable-options --show-output --nocapture
188    #[test]
189    fn test_fn() {
190        call(|a: String| {
191            println!("--->{}", a);
192            Ok("hello")
193        });
194    }
195}