Skip to content

Commit d93e772

Browse files
committed
fiber: refactor fiber builder using typestates
1 parent 6664684 commit d93e772

File tree

1 file changed

+37
-31
lines changed

1 file changed

+37
-31
lines changed

tarantool/src/fiber.rs

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -200,21 +200,47 @@ impl<'a, T> Fiber<'a, T> {
200200
/// The [`fiber::start`](start), [`fiber::start_unit`](start_unit),
201201
/// [`fiber::defer`](defer) and [`fiber::defer_unit`](defer_unit) free functions
202202
/// use a `Builder` with default configuration and unwraps its return value.
203-
pub struct Builder {
203+
pub struct Builder<F> {
204204
name: Option<String>,
205205
attr: Option<FiberAttr>,
206+
f: F,
206207
}
207208

208-
impl Builder {
209+
/// This is *typestate* helper type representing a state of a [`Builder`] that
210+
/// hasn't been assigned a fiber function yet.
211+
pub struct NoFunc;
212+
213+
/// This is *typestate* helper type representing a state of a [`Builder`] that
214+
/// has already been assigned a fiber function.
215+
pub struct HasFunc<F, T>(F)
216+
where
217+
F: FnOnce() -> T;
218+
219+
impl Builder<NoFunc> {
209220
/// Generates the base configuration for spawning a fiber, from which
210221
/// configuration methods can be chained.
211222
pub fn new() -> Self {
212223
Builder {
213224
name: None,
214225
attr: None,
226+
f: NoFunc,
227+
}
228+
}
229+
230+
/// Sets the callee function for the new fiber.
231+
pub fn callee<F, T>(self, f: F) -> Builder<HasFunc<F, T>>
232+
where
233+
F: FnOnce() -> T,
234+
{
235+
Builder {
236+
name: self.name,
237+
attr: self.attr,
238+
f: HasFunc(f),
215239
}
216240
}
241+
}
217242

243+
impl<F> Builder<F> {
218244
/// Names the fiber-to-be.
219245
///
220246
/// The name must not contain null bytes (`\0`).
@@ -224,51 +250,31 @@ impl Builder {
224250
}
225251

226252
/// Sets the size of the stack (in bytes) for the new fiber.
253+
///
254+
/// This function performs some runtime tests to validate the given stack
255+
/// size. If `stack_size` is invalid then [`Error::Tarantool`] will be
256+
/// returned.
257+
///
258+
/// [`Error::Tarantool`]: crate::error::Error::Tarantool
227259
pub fn stack_size(mut self, stack_size: usize) -> Result<Self> {
228260
let mut attr = FiberAttr::new();
229261
attr.set_stack_size(stack_size)?;
230262
self.attr = Some(attr);
231263
Ok(self)
232264
}
233-
234-
/// Sets the callee function for the new fiber.
235-
///
236-
/// Returns a [`CalleeBuilder`] taking ownership of `self`.
237-
pub fn callee<F, T>(self, f: F) -> CalleeBuilder<F, T>
238-
where
239-
F: FnOnce() -> T,
240-
{
241-
CalleeBuilder { builder: self, f: f }
242-
}
243-
}
244-
245-
////////////////////////////////////////////////////////////////////////////////
246-
/// CalleeBuilder
247-
////////////////////////////////////////////////////////////////////////////////
248-
249-
/// An intermediate fiber factory specialized for the given fiber function.
250-
///
251-
/// This type exists to avoid forcing [`Builder`] to know about the type of the
252-
/// function.
253-
pub struct CalleeBuilder<F, T>
254-
where
255-
F: FnOnce() -> T,
256-
{
257-
builder: Builder,
258-
f: F,
259265
}
260266

261267
macro_rules! inner_spawn {
262268
($self:expr, $fiber:tt) => {
263269
{
264-
let Self { builder: Builder { name, attr }, f } = $self;
270+
let Self { name, attr, f: HasFunc(f) } = $self;
265271
let name = name.unwrap_or_else(|| "<rust>".into());
266272
Ok($fiber::new(name, f, attr.as_ref())?.spawn())
267273
}
268274
};
269275
}
270276

271-
impl<F, T> CalleeBuilder<F, T>
277+
impl<F, T> Builder<HasFunc<F, T>>
272278
where
273279
F: FnOnce() -> T,
274280
{
@@ -289,7 +295,7 @@ where
289295
}
290296
}
291297

292-
impl<F> CalleeBuilder<F, ()>
298+
impl<F> Builder<HasFunc<F, ()>>
293299
where
294300
F: FnOnce(),
295301
{

0 commit comments

Comments
 (0)