1 //! Wrapper structs for the generic `Function` and `Method` traits
2 use std::sync::Arc;
3
4 use crate::host::from_polar::FromPolarList;
5 use crate::host::to_polar::{PolarIterator, ToPolar, ToPolarResult};
6
7 use super::class::{Class, Instance};
8 use super::method::{Function, Method};
9 use super::{Host, PolarValue};
10
join<A, B>(left: crate::Result<A>, right: crate::Result<B>) -> crate::Result<(A, B)>11 fn join<A, B>(left: crate::Result<A>, right: crate::Result<B>) -> crate::Result<(A, B)> {
12 left.and_then(|l| right.map(|r| (l, r)))
13 }
14
15 type TypeErasedFunction<R> = Arc<dyn Fn(Vec<PolarValue>) -> crate::Result<R> + Send + Sync>;
16 type TypeErasedMethod<R> =
17 Arc<dyn Fn(&Instance, Vec<PolarValue>, &mut Host) -> crate::Result<R> + Send + Sync>;
18
19 #[derive(Clone)]
20 pub struct RegisterHook(Arc<dyn Fn(&mut crate::Oso) -> crate::Result<()> + Send + Sync + 'static>);
21
22 impl RegisterHook {
new<F>(f: F) -> Self where F: Fn(&mut crate::Oso) -> crate::Result<()> + Send + Sync + 'static,23 pub fn new<F>(f: F) -> Self
24 where
25 F: Fn(&mut crate::Oso) -> crate::Result<()> + Send + Sync + 'static,
26 {
27 RegisterHook(Arc::new(f))
28 }
29
call(&self, oso: &mut crate::Oso) -> crate::Result<()>30 pub fn call(&self, oso: &mut crate::Oso) -> crate::Result<()> {
31 (self.0)(oso)
32 }
33 }
34
35 #[derive(Clone)]
36 pub struct Constructor(TypeErasedFunction<Instance>);
37
38 impl Constructor {
new<Args, F>(f: F) -> Self where Args: FromPolarList, F: Function<Args>, F::Result: Send + Sync + 'static,39 pub fn new<Args, F>(f: F) -> Self
40 where
41 Args: FromPolarList,
42 F: Function<Args>,
43 F::Result: Send + Sync + 'static,
44 {
45 Constructor(Arc::new(move |args: Vec<PolarValue>| {
46 Args::from_polar_list(&args).map(|args| Instance::new(f.invoke(args)))
47 }))
48 }
49
invoke(&self, args: Vec<PolarValue>) -> crate::Result<Instance>50 pub fn invoke(&self, args: Vec<PolarValue>) -> crate::Result<Instance> {
51 self.0(args)
52 }
53 }
54
55 #[derive(Clone)]
56 pub struct AttributeGetter(
57 Arc<dyn Fn(&Instance, &mut Host) -> crate::Result<PolarValue> + Send + Sync>,
58 );
59
60 impl AttributeGetter {
new<T, F, R>(f: F) -> Self where T: 'static, F: Fn(&T) -> R + Send + Sync + 'static, R: ToPolarResult,61 pub fn new<T, F, R>(f: F) -> Self
62 where
63 T: 'static,
64 F: Fn(&T) -> R + Send + Sync + 'static,
65 R: ToPolarResult,
66 {
67 Self(Arc::new(move |receiver, host: &mut Host| {
68 let receiver = receiver
69 .downcast(Some(&host))
70 .map_err(|e| e.invariant().into());
71 receiver.map(&f).and_then(|v| v.to_polar_result())
72 }))
73 }
74
invoke(&self, receiver: &Instance, host: &mut Host) -> crate::Result<PolarValue>75 pub fn invoke(&self, receiver: &Instance, host: &mut Host) -> crate::Result<PolarValue> {
76 self.0(receiver, host)
77 }
78 }
79
80 #[derive(Clone)]
81 pub struct InstanceMethod(TypeErasedMethod<PolarValue>);
82
83 impl InstanceMethod {
new<T, F, Args>(f: F) -> Self where Args: FromPolarList, F: Method<T, Args>, F::Result: ToPolarResult, T: 'static,84 pub fn new<T, F, Args>(f: F) -> Self
85 where
86 Args: FromPolarList,
87 F: Method<T, Args>,
88 F::Result: ToPolarResult,
89 T: 'static,
90 {
91 Self(Arc::new(
92 move |receiver: &Instance, args: Vec<PolarValue>, host: &mut Host| {
93 let receiver = receiver
94 .downcast(Some(&host))
95 .map_err(|e| e.invariant().into());
96
97 let args = Args::from_polar_list(&args);
98
99 join(receiver, args)
100 .and_then(|(receiver, args)| f.invoke(receiver, args).to_polar_result())
101 },
102 ))
103 }
104
new_iterator<T, F, Args, I>(f: F) -> Self where Args: FromPolarList, F: Method<T, Args>, F::Result: IntoIterator<Item = I>, <<F as Method<T, Args>>::Result as IntoIterator>::IntoIter: Iterator<Item = I> + Clone + Send + Sync + 'static, I: ToPolarResult, T: 'static,105 pub fn new_iterator<T, F, Args, I>(f: F) -> Self
106 where
107 Args: FromPolarList,
108 F: Method<T, Args>,
109 F::Result: IntoIterator<Item = I>,
110 <<F as Method<T, Args>>::Result as IntoIterator>::IntoIter:
111 Iterator<Item = I> + Clone + Send + Sync + 'static,
112 I: ToPolarResult,
113 T: 'static,
114 {
115 Self(Arc::new(
116 move |receiver: &Instance, args: Vec<PolarValue>, host: &mut Host| {
117 let receiver = receiver
118 .downcast(Some(&host))
119 .map_err(|e| e.invariant().into());
120
121 let args = Args::from_polar_list(&args);
122
123 join(receiver, args)
124 .map(|(receiver, args)| {
125 PolarIterator::new(f.invoke(receiver, args).into_iter())
126 })
127 .map(|results| results.to_polar())
128 },
129 ))
130 }
131
invoke( &self, receiver: &Instance, args: Vec<PolarValue>, host: &mut Host, ) -> crate::Result<PolarValue>132 pub fn invoke(
133 &self,
134 receiver: &Instance,
135 args: Vec<PolarValue>,
136 host: &mut Host,
137 ) -> crate::Result<PolarValue> {
138 self.0(receiver, args, host)
139 }
140
from_class_method(name: String) -> Self141 pub fn from_class_method(name: String) -> Self {
142 Self(Arc::new(
143 move |receiver: &Instance, args: Vec<PolarValue>, host: &mut Host| {
144 receiver
145 .downcast::<Class>(Some(&host))
146 .map_err(|e| e.invariant().into())
147 .and_then(|class| {
148 tracing::trace!(class = %class.name, method=%name, "class_method");
149 class.call(&name, args)
150 })
151 },
152 ))
153 }
154 }
155
156 #[derive(Clone)]
157 pub struct ClassMethod(TypeErasedFunction<PolarValue>);
158
159 impl ClassMethod {
new<F, Args>(f: F) -> Self where Args: FromPolarList, F: Function<Args>, F::Result: ToPolarResult,160 pub fn new<F, Args>(f: F) -> Self
161 where
162 Args: FromPolarList,
163 F: Function<Args>,
164 F::Result: ToPolarResult,
165 {
166 Self(Arc::new(move |args: Vec<PolarValue>| {
167 Args::from_polar_list(&args).and_then(|args| f.invoke(args).to_polar_result())
168 }))
169 }
170
invoke(&self, args: Vec<PolarValue>) -> crate::Result<PolarValue>171 pub fn invoke(&self, args: Vec<PolarValue>) -> crate::Result<PolarValue> {
172 self.0(args)
173 }
174 }
175