1use std::sync::{Arc, RwLock};
2
3pub trait SafeGeneratorTrait<T>: Send + Sync {
8 fn next_with(&self, selfish: &SafeGenerator<T>) -> Option<T>;
9 fn done(&self) -> bool;
10 fn close(&self);
11}
12
13#[derive(Clone)]
14pub struct SafeGenerator<T>(Arc<dyn SafeGeneratorTrait<T>>);
15
16impl<T> SafeGenerator<T>
17where
18 T: Clone + Send + Sync + 'static,
19{
20 pub fn from_fn(
21 generator_fn: std::sync::Arc<
22 dyn Fn(SafeGenerator<T>) -> Option<T> + std::marker::Send + std::marker::Sync,
23 >,
24 ) -> SafeGenerator<T> {
25 SafeGenerator::new(SafeGeneratorFnAdapter(RwLock::new(
26 SafeGeneratorFnAdapterStruct {
27 done: false,
28 generator_fn: generator_fn.clone(),
29 },
30 )))
31 }
32
33 pub fn new(selfish: impl SafeGeneratorTrait<T> + 'static) -> SafeGenerator<T> {
34 SafeGenerator(Arc::new(selfish))
35 }
36
37 pub fn next(&self) -> Option<T> {
38 self.0.next_with(&self)
39 }
40}
41
42impl<T> std::ops::Deref for SafeGenerator<T> {
43 type Target = dyn SafeGeneratorTrait<T>;
44 fn deref(&self) -> &Self::Target {
45 &*self.0
46 }
47}
48
49struct SafeGeneratorFnAdapterStruct<T> {
50 done: bool,
51 generator_fn: std::sync::Arc<
52 dyn Fn(SafeGenerator<T>) -> Option<T> + std::marker::Send + std::marker::Sync,
53 >,
54}
55
56struct SafeGeneratorFnAdapter<T>(RwLock<SafeGeneratorFnAdapterStruct<T>>);
58
59impl<T> SafeGeneratorFnAdapter<T> {
60 pub fn done(&self) -> bool {
61 self.0.read().unwrap().done
62 }
63
64 pub fn generator_fn(
65 &self,
66 ) -> Arc<dyn Fn(SafeGenerator<T>) -> Option<T> + std::marker::Send + std::marker::Sync> {
67 self.0.read().unwrap().generator_fn.clone()
68 }
69
70 pub fn close(&self) {
71 self.0.write().unwrap().done = true;
72 }
73}
74
75impl<T> SafeGeneratorTrait<T> for SafeGeneratorFnAdapter<T>
76where
77 T: Clone + 'static,
78{
79 fn next_with(&self, selfish: &SafeGenerator<T>) -> Option<T> {
80 if self.done() {
81 return None;
82 }
83 let result = (self.generator_fn())(selfish.clone());
84 if result.is_none() {
85 self.close();
86 }
87 result
88 }
89
90 fn done(&self) -> bool {
91 self.done()
92 }
93
94 fn close(&self) {
95 self.close();
96 }
97}