1use crate::trait_group::c_void;
17use std::prelude::v1::*;
18
19#[repr(transparent)]
21#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
22pub struct OpaqueCallback<'a, T: 'a>(Callback<'a, c_void, T>);
23
24impl<'a, T> OpaqueCallback<'a, T> {
25 #[must_use = "this value is the stopping condition"]
26 pub fn call(&mut self, arg: T) -> bool {
27 (self.0.func)(self.0.context, arg)
28 }
29}
30
31#[repr(C)]
32#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
33pub struct Callback<'a, T: 'a, F> {
34 context: &'a mut T,
35 func: extern "C" fn(&mut T, F) -> bool,
36}
37
38impl<'a, T, F> From<Callback<'a, T, F>> for OpaqueCallback<'a, F> {
39 fn from(callback: Callback<'a, T, F>) -> Self {
40 Self(callback.into_opaque())
41 }
42}
43
44impl<'a, T, F> Callback<'a, T, F> {
45 pub fn into_opaque(self) -> Callback<'a, c_void, F> {
46 unsafe {
47 Callback {
48 context: &mut *(self.context as *mut T as *mut c_void),
49 func: std::mem::transmute(self.func),
50 }
51 }
52 }
53
54 pub fn new(context: &'a mut T, func: extern "C" fn(&mut T, F) -> bool) -> Self {
55 Self { context, func }
56 }
57}
58
59impl<'a, T: FnMut(F) -> bool, F> From<&'a mut T> for OpaqueCallback<'a, F> {
60 fn from(func: &'a mut T) -> Self {
61 extern "C" fn callback<T: FnMut(F) -> bool, F>(func: &mut T, context: F) -> bool {
62 func(context)
63 }
64
65 Callback {
66 context: func,
67 func: callback::<T, F>,
68 }
69 .into()
70 }
71}
72
73impl<'a, T> From<&'a mut Vec<T>> for OpaqueCallback<'a, T> {
74 fn from(vec: &'a mut Vec<T>) -> Self {
75 extern "C" fn callback<T>(v: &mut Vec<T>, context: T) -> bool {
76 v.push(context);
77 true
78 }
79
80 Callback {
81 context: vec,
82 func: callback::<T>,
83 }
84 .into()
85 }
86}
87
88impl<'a, T> std::iter::Extend<T> for OpaqueCallback<'a, T> {
89 fn extend<F: IntoIterator<Item = T>>(&mut self, iter: F) {
90 for item in iter {
91 if !self.call(item) {
92 break;
93 }
94 }
95 }
96}
97
98pub trait FeedCallback<T> {
99 fn feed_into_mut(self, callback: &mut OpaqueCallback<T>) -> usize;
100
101 fn feed_into(self, mut callback: OpaqueCallback<T>) -> usize
102 where
103 Self: Sized,
104 {
105 self.feed_into_mut(&mut callback)
106 }
107}
108
109impl<I: std::iter::IntoIterator<Item = T>, T> FeedCallback<T> for I {
110 fn feed_into_mut(self, callback: &mut OpaqueCallback<T>) -> usize {
111 let mut cnt = 0;
112 for v in self {
113 cnt += 1;
114 if !callback.call(v) {
115 break;
116 }
117 }
118 cnt
119 }
120}
121
122pub trait FromExtend<T>: Extend<T> + Sized {
123 #[allow(clippy::wrong_self_convention)]
124 fn from_extend(&mut self) -> OpaqueCallback<T> {
125 extern "C" fn callback<C: Extend<T>, T>(v: &mut C, context: T) -> bool {
126 v.extend(Some(context));
127 true
128 }
129
130 Callback {
131 context: self,
132 func: callback::<Self, T>,
133 }
134 .into()
135 }
136}
137
138impl<C: Extend<T>, T> FromExtend<T> for C {}
139
140pub trait Callbackable<T> {
141 fn call(&mut self, data: T) -> bool;
142}
143
144impl<T> Callbackable<T> for &mut OpaqueCallback<'_, T> {
145 fn call(&mut self, data: T) -> bool {
146 (*self).call(data)
147 }
148}
149
150impl<T> Callbackable<T> for OpaqueCallback<'_, T> {
151 fn call(&mut self, data: T) -> bool {
152 (self.0.func)(self.0.context, data)
153 }
154}
155
156impl<T, F: FnMut(T) -> bool> Callbackable<T> for F {
157 fn call(&mut self, data: T) -> bool {
158 (*self)(data)
159 }
160}