hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

stream.ha (1691B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use errors;
      5 
      6 // A stream is a pointer to a [[vtable]] which allows for user-defined I/O
      7 // abstractions to implement some subset of read, write, seek, close, and other
      8 // I/O functionality in userspace. Embed to create a custom stream type:
      9 //
     10 //	export type my_stream = struct {
     11 //		vtable: io::stream,
     12 //		fd: int,
     13 //	};
     14 //
     15 //	const my_vtable: io::vtable = io::vtable {
     16 //		reader = &my_stream_read,
     17 //		writer = &my_stream_write,
     18 //		closer = null,
     19 //		...
     20 //	};
     21 //
     22 //	export fn open(path: str) my_stream = {
     23 //		let fd = // ...
     24 //		return my_stream {
     25 //			vtable = &my_vtable,
     26 //			fd = fd,
     27 //			...
     28 //		});
     29 //	};
     30 //
     31 //	let stream = open("example");
     32 //	io::read(&stream, buf)!;
     33 export type stream = *vtable;
     34 
     35 // The vtable type defines a set of virtual functions for a [[stream]].
     36 export type vtable = struct {
     37 	reader: nullable *reader,
     38 	writer: nullable *writer,
     39 	closer: nullable *closer,
     40 	seeker: nullable *seeker,
     41 	copier: nullable *copier,
     42 };
     43 
     44 fn st_read(s: *stream, buf: []u8) (size | EOF | error) = {
     45 	match (s.reader) {
     46 	case null =>
     47 		return errors::unsupported;
     48 	case let r: *reader =>
     49 		return r(s, buf);
     50 	};
     51 };
     52 
     53 fn st_write(s: *stream, buf: const []u8) (size | error) = {
     54 	match (s.writer) {
     55 	case null =>
     56 		return errors::unsupported;
     57 	case let w: *writer =>
     58 		return w(s, buf);
     59 	};
     60 };
     61 
     62 fn st_close(s: *stream) (void | error) = {
     63 	match (s.closer) {
     64 	case null => void;
     65 	case let c: *closer =>
     66 		c(s)?;
     67 	};
     68 };
     69 
     70 fn st_seek(s: *stream, off: off, w: whence) (off | error) = {
     71 	match (s.seeker) {
     72 	case null =>
     73 		return errors::unsupported;
     74 	case let sk: *seeker =>
     75 		return sk(s, off, w);
     76 	};
     77 };