blob: 03b3ee18cd87abf8fabb53f468cf8175de635095 [file] [log] [blame]
Jorge Canizales30697c92015-02-17 17:09:14 -08001#import <Foundation/Foundation.h>
2
3#import "GRXWriteable.h"
4
5typedef NS_ENUM(NSInteger, GRXWriterState) {
6
7 // The writer has not yet been given a writeable to which it can push its
8 // values. To have an writer transition to the Started state, send it a
9 // startWithWriteable: message.
10 //
11 // An writer's state cannot be manually set to this value.
12 GRXWriterStateNotStarted,
13
14 // The writer might push values to the writeable at any moment.
15 GRXWriterStateStarted,
16
17 // The writer is temporarily paused, and won't send any more values to the
18 // writeable unless its state is set back to Started. The writer might still
19 // transition to the Finished state at any moment, and is allowed to send
20 // didFinishWithError: to its writeable.
21 //
22 // Not all implementations of writer have to support pausing, and thus
23 // trying to set an writer's state to this value might have no effect.
24 GRXWriterStatePaused,
25
26 // The writer has released its writeable and won't interact with it anymore.
27 //
28 // One seldomly wants to set an writer's state to this value, as its
29 // writeable isn't notified with a didFinishWithError: message. Instead, sending
30 // finishWithError: to the writer will make it notify the writeable and then
31 // transition to this state.
32 GRXWriterStateFinished
33};
34
35// An object that conforms to this protocol can produce, on demand, a sequence
36// of values. The sequence may be produced asynchronously, and it may consist of
37// any number of elements, including none or an infinite number.
38//
39// GRXWriter is the active dual of NSEnumerator. The difference between them
40// is thus whether the object plays an active or passive role during usage: A
41// user of NSEnumerator pulls values off it, and passes the values to a writeable.
42// A user of GRXWriter, though, just gives it a writeable, and the
43// GRXWriter instance pushes values to the writeable. This makes this protocol
44// suitable to represent a sequence of future values, as well as collections
45// with internal iteration.
46//
47// An instance of GRXWriter can start producing values after a writeable is
48// passed to it. It can also be commanded to finish the sequence immediately
49// (with an optional error). Finally, it can be asked to pause, but the
50// conforming instance is not required to oblige.
51//
52// Unless otherwise indicated by a conforming class, no messages should be sent
53// concurrently to a GRXWriter. I.e., conforming classes aren't required to
54// be thread-safe.
55@protocol GRXWriter <NSObject>
56
57// This property can be used to query the current state of the writer, which
58// determines how it might currently use its writeable. Some state transitions can
59// be triggered by setting this property to the corresponding value, and that's
60// useful for advanced use cases like pausing an writer. For more details,
61// see the documentation of the enum.
62@property(nonatomic) GRXWriterState state;
63
64// Start sending messages to the writeable. Messages may be sent before the method
65// returns, or they may be sent later in the future. See GRXWriteable.h for the
66// different messages a writeable can receive.
67//
68// If this writer draws its values from an external source (e.g. from the
69// filesystem or from a server), calling this method will commonly trigger side
70// effects (like network connections).
71//
72// This method might only be called on writers in the NotStarted state.
73- (void)startWithWriteable:(id<GRXWriteable>)writeable;
74
75// Send didFinishWithError:errorOrNil immediately to the writeable, and don't send
76// any more messages to it.
77//
78// This method might only be called on writers in the Started or Paused
79// state.
80//
81// TODO(jcanizales): Consider adding some guarantee about the immediacy of that
82// stopping. I know I've relied on it in part of the code that uses this, but
83// can't remember the details in the presence of concurrency.
84- (void)finishWithError:(NSError *)errorOrNil;
85@end
86
87// A "proxy" class that simply forwards values, completion, and errors from its
88// input writer to its writeable.
89// It is useful as a superclass for pipes that act as a transformation of their
90// input writer, and for classes that represent objects with input and
91// output sequences of values, like an RPC.
92@interface GRXWriter : NSObject<GRXWriter>
93- (instancetype)initWithWriter:(id<GRXWriter>)writer NS_DESIGNATED_INITIALIZER;
94@end