Struct generator::Scope

source ·
pub struct Scope<'scope, 'a, A, T> { /* private fields */ }
Expand description

passed in scope type it not use the context to pass data, but keep it’s own data ref this struct provide both compile type info and runtime data

Implementations§

source§

impl<'scope, 'a, A, T> Scope<'scope, 'a, A, T>

source

pub fn yield_with(&mut self, v: T)

yield something without catch passed in para

Examples found in repository?
examples/pipe.rs (line 8)
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    fn square<'a, T: Iterator<Item = u32> + Send + 'a>(input: T) -> Generator<'a, (), u32> {
        Gn::new_scoped(|mut s| {
            for i in input {
                s.yield_with(i * i);
            }
            done!();
        })
    }

    // fn sum<'a, T: Iterator<Item = u32> + 'a>(input: T) -> impl Iterator<Item = u32> + 'a {
    fn sum<'a, T: Iterator<Item = u32> + Send + 'a>(input: T) -> Generator<'a, (), u32> {
        Gn::new_scoped(|mut s| {
            let mut acc = 0;
            for i in input {
                acc += i;
                s.yield_with(acc);
            }
            done!();
        })
    }
More examples
Hide additional examples
examples/number.rs (line 9)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fn factors(n: u32) -> Generator<'static, (), u32> {
    Gn::new_scoped(move |mut s| {
        if n == 0 {
            return 0;
        }

        s.yield_with(1);

        for i in 2..n {
            if n % i == 0 {
                s.yield_with(i);
            }
        }
        done!();
    })
}
examples/cd.rs (line 46)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
fn main() {
    let mut cd_player = Gn::new_scoped(|mut s| {
        let mut state = Stopped;
        loop {
            // println!("{:?}", *state);
            // in release mod without this there is bugs!!!!! (rustc 1.59.0 (9d1b2106e 2022-02-23))
            std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::AcqRel);

            match state {
                Stopped => match s.get_yield() {
                    Some(Play(t)) => {
                        println!("I'm playing {t}");
                        state = Playing;
                    }
                    Some(Stop) => println!("I'm already stopped"),
                    _ => unreachable!("some thing wrong"),
                },

                Playing => match s.get_yield() {
                    Some(Stop) => {
                        println!("I'm stopped");
                        state = Stopped;
                    }
                    Some(Play(_)) => println!("should first stop"),
                    _ => unreachable!("some thing wrong"),
                },
            }

            s.yield_with(state);
        }
    });

    for _ in 0..1000 {
        let ret = cd_player.send(Play("hello world"));
        assert_eq!(ret, Playing);
        let ret = cd_player.send(Play("hello another day"));
        assert_eq!(ret, Playing);
        let ret = cd_player.send(Stop);
        assert_eq!(ret, Stopped);
        let ret = cd_player.send(Stop);
        assert_eq!(ret, Stopped);
        let ret = cd_player.send(Play("hello another day"));
        assert_eq!(ret, Playing);
        let ret = cd_player.send(Stop);
        assert_eq!(ret, Stopped);
    }
}
source

pub fn get_yield(&mut self) -> Option<A>

get current generator send para

Examples found in repository?
examples/cd.rs (line 27)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
fn main() {
    let mut cd_player = Gn::new_scoped(|mut s| {
        let mut state = Stopped;
        loop {
            // println!("{:?}", *state);
            // in release mod without this there is bugs!!!!! (rustc 1.59.0 (9d1b2106e 2022-02-23))
            std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::AcqRel);

            match state {
                Stopped => match s.get_yield() {
                    Some(Play(t)) => {
                        println!("I'm playing {t}");
                        state = Playing;
                    }
                    Some(Stop) => println!("I'm already stopped"),
                    _ => unreachable!("some thing wrong"),
                },

                Playing => match s.get_yield() {
                    Some(Stop) => {
                        println!("I'm stopped");
                        state = Stopped;
                    }
                    Some(Play(_)) => println!("should first stop"),
                    _ => unreachable!("some thing wrong"),
                },
            }

            s.yield_with(state);
        }
    });

    for _ in 0..1000 {
        let ret = cd_player.send(Play("hello world"));
        assert_eq!(ret, Playing);
        let ret = cd_player.send(Play("hello another day"));
        assert_eq!(ret, Playing);
        let ret = cd_player.send(Stop);
        assert_eq!(ret, Stopped);
        let ret = cd_player.send(Stop);
        assert_eq!(ret, Stopped);
        let ret = cd_player.send(Play("hello another day"));
        assert_eq!(ret, Playing);
        let ret = cd_player.send(Stop);
        assert_eq!(ret, Stopped);
    }
}
source

pub unsafe fn yield_unsafe(&mut self, v: T) -> Option<A>

yield and get the send para

§Safety

When yield out, the reference of the captured data must be still valid normally, you should always call the drop of the generator

Examples found in repository?
examples/lifetime.rs (line 13)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fn main() {
    let str = "foo".to_string();

    let mut gen = generator::Gn::new_scoped(|mut s| {
        std::thread::scope(|s2| {
            s2.spawn(|| {
                std::thread::sleep(std::time::Duration::from_millis(500));
                println!("{str}");
            });
            // here we can't use `yield_` because it still ref to `str`
            // `yield_` only impl for static captured lifetime
            // s.yield_(());
            unsafe { s.yield_unsafe(()) };
        });
        generator::done!();
    });

    gen.next();
    // std::mem::forget(gen);
    // drop(gen);
    // drop(str);
    std::thread::sleep(std::time::Duration::from_millis(1000));
}
source

pub unsafe fn yield_from_unsafe(&mut self, g: Generator<'_, A, T>) -> Option<A>

yield_from_unsafe the from generator must has the same type as itself

§Safety

When yield out, the reference of the captured data must be still valid normally, you should always call the drop of the generator

source§

impl<'scope, A, T> Scope<'scope, 'static, A, T>

source

pub fn yield_(&mut self, v: T) -> Option<A>

yield and get the send para

Examples found in repository?
examples/range.rs (line 8)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fn main() {
    let n = 100000;
    let range = Gn::new_scoped(move |mut s| {
        let mut num = 0;
        while num < n {
            s.yield_(num);
            num += 1;
        }
        done!();
    });

    let sum: usize = range.sum();
    println!("sum ={sum}");
}
More examples
Hide additional examples
examples/fib.rs (line 9)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fn main() {
    let g = Gn::new_scoped(|mut s| {
        let (mut a, mut b) = (0, 1);
        while b < 200 {
            std::mem::swap(&mut a, &mut b);
            b += a;
            s.yield_(b);
        }
        done!();
    });

    for i in g {
        println!("{i}");
    }
}
source

pub fn yield_from(&mut self, g: Generator<'_, A, T>) -> Option<A>

yield_from the from generator must has the same type as itself

Examples found in repository?
examples/yield_from.rs (line 17)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fn main() {
    let g1 = Gn::new(|| xrange(0, 10));
    let g2 = Gn::new(|| xrange(10, 20));

    let g = Gn::new_scoped(|mut s| {
        s.yield_from(g1);
        s.yield_from(g2);
        done!();
    });

    g.fold(0, |sum, x| {
        println!("i={}, sum={}", x, sum + x);
        sum + x
    });
}

Auto Trait Implementations§

§

impl<'scope, 'a, A, T> RefUnwindSafe for Scope<'scope, 'a, A, T>

§

impl<'scope, 'a, A, T> Send for Scope<'scope, 'a, A, T>
where A: Send, T: Send,

§

impl<'scope, 'a, A, T> Sync for Scope<'scope, 'a, A, T>
where A: Sync, T: Sync,

§

impl<'scope, 'a, A, T> Unpin for Scope<'scope, 'a, A, T>

§

impl<'scope, 'a, A, T> !UnwindSafe for Scope<'scope, 'a, A, T>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.