aramid/state.rs
1/// Fiber state.
2#[derive(Debug, PartialEq)]
3#[must_use]
4pub enum State<Y, R> {
5 /// Yielded value
6 Yield(Y),
7 /// Done processing
8 Done(R),
9}
10
11impl<Y, R> State<Y, R> {
12 /// Unwrap the value wrapped in `Yield`.
13 ///
14 /// # Panics
15 ///
16 /// This function panics, if the state is `Done`.
17 ///
18 /// # Examples
19 ///
20 /// ```rust
21 /// # use aramid::State;
22 /// let state = State::<u8, ()>::Yield(9);
23 ///
24 /// assert_eq!(state.unwrap(), 9);
25 /// ```
26 #[inline]
27 pub fn unwrap(self) -> Y {
28 self.expect("should be Yield")
29 }
30
31 /// Unwrap the value wrapped in `Yield`.
32 ///
33 /// # Panics
34 ///
35 /// This function panics with a custom message, if the state is `Done`.
36 ///
37 /// # Examples
38 ///
39 /// ```rust
40 /// # use aramid::State;
41 /// let state = State::<u8, ()>::Yield(9);
42 ///
43 /// assert_eq!(state.expect("not done yet"), 9);
44 /// ```
45 #[inline]
46 pub fn expect(
47 self,
48 msg: &str,
49 ) -> Y {
50 match self {
51 State::Yield(yld) => yld,
52 State::Done(_) => panic!("{msg}"),
53 }
54 }
55
56 /// Unwrap the value wrapped in `Done`.
57 ///
58 /// # Panics
59 ///
60 /// This function panics, if the state is `Yield`.
61 ///
62 /// # Examples
63 ///
64 /// ```rust
65 /// # use aramid::State;
66 /// let state = State::<(), u8>::Done(9);
67 ///
68 /// assert_eq!(state.unwrap_done(), 9);
69 /// ```
70 #[inline]
71 pub fn unwrap_done(self) -> R {
72 self.expect_done("should be Done")
73 }
74
75 /// Unwrap the value wrapped in `Done`.
76 ///
77 /// # Panics
78 ///
79 /// This function panics with a custom message, if the state is `Yield`.
80 ///
81 /// # Examples
82 ///
83 /// ```rust
84 /// # use aramid::State;
85 /// let state = State::<(), u8>::Done(9);
86 ///
87 /// assert_eq!(state.expect_done("should be done by now"), 9);
88 /// ```
89 #[inline]
90 pub fn expect_done(
91 self,
92 msg: &str,
93 ) -> R {
94 match self {
95 State::Yield(_) => panic!("{msg}"),
96 State::Done(out) => out,
97 }
98 }
99
100 /// Return true, if the state is `Yield`, otherwise return false.
101 ///
102 /// # Examples
103 ///
104 /// ```rust
105 /// # use aramid::State;
106 /// let state = State::<u8, ()>::Yield(9);
107 ///
108 /// assert!(state.is_yield());
109 /// ```
110 pub fn is_yield(&self) -> bool {
111 match self {
112 State::Yield(_) => true,
113 State::Done(_) => false,
114 }
115 }
116
117 /// Return true, if the state is `Done`, otherwise return false.
118 ///
119 /// # Examples
120 ///
121 /// ```rust
122 /// # use aramid::State;
123 /// let state = State::<(), u8>::Done(9);
124 ///
125 /// assert!(state.is_done());
126 /// ```
127 pub fn is_done(&self) -> bool {
128 match self {
129 State::Yield(_) => false,
130 State::Done(_) => true,
131 }
132 }
133
134 /// Return the value of `Done`, or apply operator `OP` on the value of
135 /// `Yield`.
136 ///
137 /// Returns `None` if the value was `Yield`.
138 pub fn done_or<OP>(
139 &mut self,
140 f: OP,
141 ) -> Option<&mut R>
142 where
143 OP: FnOnce(&mut Y),
144 {
145 match self {
146 Self::Done(out) => Some(out),
147 Self::Yield(fbr) => {
148 f(fbr);
149 None
150 }
151 }
152 }
153
154 /// Return the result of `OP` applied on the value of `Yield`.
155 ///
156 /// Return `None` if the value is `Done`.
157 pub fn yield_and<OP, T>(
158 &mut self,
159 f: OP,
160 ) -> Option<T>
161 where
162 OP: FnOnce(&mut Y) -> T,
163 {
164 if let Self::Yield(fbr) = self {
165 Some(f(fbr))
166 } else {
167 None
168 }
169 }
170}