@@ -7,10 +7,10 @@ const queue = @import("../queue.zig");
77/// Options for creating a stream type. Each of the options makes the
88/// functionality available for the stream.
99pub const Options = struct {
10- read : ReadMethod ,
11- write : WriteMethod ,
12- close : bool ,
13- poll : bool ,
10+ read : ReadMethod = .none ,
11+ write : WriteMethod = .none ,
12+ close : bool = false ,
13+ poll : bool = false ,
1414
1515 /// True to schedule the read/write on the threadpool.
1616 threadpool : bool = false ,
@@ -104,21 +104,35 @@ pub fn Shared(comptime xev: type) type {
104104 };
105105}
106106
107- /// Creates a stream type that is meant to be embedded within other
108- /// types using "usingnamespace". A stream is something that supports read,
109- /// write, close, etc. The exact operations supported are defined by the
110- /// "options" struct.
107+ /// Creates a stream type that is meant to be embedded within other types.
108+ /// A stream is something that supports read, write, close, etc. The exact
109+ /// operations supported are defined by the "options" struct.
111110///
112111/// T requirements:
113112/// - field named "fd" of type fd_t or socket_t
114113/// - decl named "initFd" to initialize a new T from a fd
115114///
116115pub fn Stream (comptime xev : type , comptime T : type , comptime options : Options ) type {
117116 return struct {
118- pub usingnamespace if (options .close ) Closeable (xev , T , options ) else struct {};
119- pub usingnamespace if (options .poll ) Pollable (xev , T , options ) else struct {};
120- pub usingnamespace if (options .read != .none ) Readable (xev , T , options ) else struct {};
121- pub usingnamespace if (options .write != .none ) Writeable (xev , T , options ) else struct {};
117+ const C_ : ? type = if (options .close ) Closeable (xev , T , options ) else null ;
118+ pub const close = if (C_ ) | C | C .close else {};
119+
120+ const P_ : ? type = if (options .poll ) Pollable (xev , T , options ) else null ;
121+ pub const poll = if (P_ ) | P | poll : {
122+ if (! @hasDecl (P , "poll" )) break :poll {};
123+ break :poll P .poll ;
124+ } else {};
125+
126+ const R_ : ? type = if (options .read != .none ) Readable (xev , T , options ) else null ;
127+ pub const read = if (R_ ) | R | R .read else {};
128+
129+ const W_ : ? type = if (options .write != .none ) Writeable (xev , T , options ) else null ;
130+ pub const writeInit = if (W_ ) | W | writeInit : {
131+ if (xev .dynamic ) break :writeInit {};
132+ break :writeInit W .writeInit ;
133+ } else {};
134+ pub const write = if (W_ ) | W | W .write else null ;
135+ pub const queueWrite = if (W_ ) | W | W .queueWrite else {};
122136 };
123137}
124138
@@ -1034,13 +1048,19 @@ pub fn GenericStream(comptime xev: type) type {
10341048
10351049 pub const Union = xev .Union (&.{"Stream" });
10361050
1037- pub usingnamespace Stream (xev , Self , .{
1051+ const S = Stream (xev , Self , .{
10381052 .close = true ,
10391053 .poll = true ,
10401054 .read = .read ,
10411055 .write = .write ,
10421056 .type = "Stream" ,
10431057 });
1058+ pub const close = S .close ;
1059+ pub const poll = S .poll ;
1060+ pub const read = S .read ;
1061+ pub const write = S .write ;
1062+ pub const writeInit = S .writeInit ;
1063+ pub const queueWrite = S .queueWrite ;
10441064
10451065 pub fn initFd (fd : std.posix.pid_t ) Self {
10461066 return .{ .backend = switch (xev .backend ) {
@@ -1075,12 +1095,18 @@ pub fn GenericStream(comptime xev: type) type {
10751095 /// The underlying file
10761096 fd : std.posix.fd_t ,
10771097
1078- pub usingnamespace Stream (xev , Self , .{
1098+ const S = Stream (xev , Self , .{
10791099 .close = true ,
10801100 .poll = true ,
10811101 .read = .read ,
10821102 .write = .write ,
10831103 });
1104+ pub const close = S .close ;
1105+ pub const poll = S .poll ;
1106+ pub const read = S .read ;
1107+ pub const write = S .write ;
1108+ pub const writeInit = S .writeInit ;
1109+ pub const queueWrite = S .queueWrite ;
10841110
10851111 /// Initialize a generic stream from a file descriptor.
10861112 pub fn initFd (fd : std.posix.fd_t ) Self {
@@ -1104,6 +1130,17 @@ pub fn GenericStream(comptime xev: type) type {
11041130
11051131fn GenericStreamTests (comptime xev : type , comptime Impl : type ) type {
11061132 return struct {
1133+ test "Stream decls" {
1134+ if (! @hasDecl (Impl , "S" )) return ;
1135+ inline for (@typeInfo (Impl .S ).@"struct" .decls ) | decl | {
1136+ const Decl = @TypeOf (@field (Impl .S , decl .name ));
1137+ if (Decl == void ) continue ;
1138+ if (! @hasDecl (Impl , decl .name )) {
1139+ @compileError ("missing decl: " ++ decl .name );
1140+ }
1141+ }
1142+ }
1143+
11071144 test "pty: child to parent" {
11081145 const testing = std .testing ;
11091146 switch (builtin .os .tag ) {
0 commit comments