temper_core/
generator.rs

1use std::sync::{Arc, RwLock};
2
3// pub trait GeneratorTrait<T> {
4//     //
5// }
6
7pub 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
56// Avoid Arc layer here because we only expose through interface trait.
57struct 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}