libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_stream.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 * Use of this source code is governed by the ISC License.
4 *
5 * src/inc/xtc_stream.h
6 * Async streams: a lazy, pull-based sequence of values with
7 * composable combinators (map, filter, for_each). A stream is
8 * nothing more than a next() function that produces the next value
9 * (or signals end-of-stream), plus a small vtable so combinators can
10 * wrap one stream in another without materializing the whole
11 * sequence -- the Elixir Stream / Rust Iterator shape.
12 *
13 * Pull-based composes naturally with the demand channel (R9): a
14 * consumer pulls one value at a time, so a slow map/filter stage
15 * exerts backpressure just by pulling more slowly. Use
16 * xtc_stream_from_demand to turn an xtc_chan_demand into a stream.
17 *
18 * Values are void*; the stream never owns them (it neither copies
19 * nor frees). A combinator's transform decides ownership.
20 */
21
22#ifndef XTC_STREAM_H
23#define XTC_STREAM_H
24
25#include "xtc_export.h"
26
27#include <stddef.h>
28
29#include "xtc.h"
30#include "xtc_chan.h"
31
32typedef struct xtc_stream xtc_stream_t;
33
34/*
35 * Pull one value. On XTC_OK, *out holds the next value. Returns
36 * XTC_E_NOTFOUND at end-of-stream, XTC_E_AGAIN if no value is available
37 * yet but the stream is not finished (the caller should retry, e.g.
38 * after a demand-channel item arrives), or another XTC_E_* on error.
39 */
40typedef int (*xtc_stream_next_fn)(void *ctx, void **out);
41
42/*
43 * PUBLIC: int xtc_stream_create __P((xtc_stream_next_fn, void *, xtc_stream_t **));
44 * PUBLIC: void xtc_stream_destroy __P((xtc_stream_t *));
45 * PUBLIC: int xtc_stream_next __P((xtc_stream_t *, void **));
46 * PUBLIC: int xtc_stream_map __P((xtc_stream_t *, void *(*)(void *, void *), void *, xtc_stream_t **));
47 * PUBLIC: int xtc_stream_filter __P((xtc_stream_t *, int (*)(void *, void *), void *, xtc_stream_t **));
48 * PUBLIC: int xtc_stream_for_each __P((xtc_stream_t *, int (*)(void *, void *), void *));
49 * PUBLIC: int xtc_stream_from_demand __P((xtc_chan_demand_t *, xtc_stream_t **));
50 */
51
52/* Create a stream from a next() function and its context. */
53XTC_API int xtc_stream_create(xtc_stream_next_fn next, void *ctx,
54 xtc_stream_t **out);
55
56/* Destroy a stream. Destroying a combinator stream (map/filter) also
57 * destroys the source stream it wraps, recursively; destroy only the
58 * outermost stream. Does not touch the underlying demand channel of a
59 * from_demand stream (the caller owns that). */
60XTC_API void xtc_stream_destroy(xtc_stream_t *s);
61
62/* Pull the next value. See xtc_stream_next_fn for the return codes. */
63XTC_API int xtc_stream_next(xtc_stream_t *s, void **out);
64
65/* map: each pulled value v becomes fn(v, user). Lazy: fn runs only when
66 * the resulting stream is pulled. The new stream OWNS `s`. */
67XTC_API int xtc_stream_map(xtc_stream_t *s,
68 void *(*fn)(void *v, void *user), void *user,
69 xtc_stream_t **out);
70
71/* filter: values for which pred(v, user) returns 0 are skipped. The new
72 * stream OWNS `s`. */
73XTC_API int xtc_stream_filter(xtc_stream_t *s,
74 int (*pred)(void *v, void *user), void *user,
75 xtc_stream_t **out);
76
77/* Drain the stream, calling fn(v, user) for each value until
78 * end-of-stream. A nonzero fn return stops early and is returned. An
79 * XTC_E_AGAIN from the source is treated as "retry": for_each spins on
80 * it, so use it only with a source that will eventually produce or
81 * finish (e.g. a fully-buffered demand channel that has been closed). */
82XTC_API int xtc_stream_for_each(xtc_stream_t *s,
83 int (*fn)(void *v, void *user), void *user);
84
85/* Adapt a demand channel into a stream: each pull grants one unit of
86 * demand and returns the next buffered item (XTC_E_AGAIN until one
87 * arrives, XTC_E_NOTFOUND once the channel is closed and drained). */
88XTC_API int xtc_stream_from_demand(xtc_chan_demand_t *ch, xtc_stream_t **out);
89
90#endif /* XTC_STREAM_H */