aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/io.rs71
1 files changed, 48 insertions, 23 deletions
diff --git a/src/lib/io.rs b/src/lib/io.rs
index 0c4eb39e..71ebc1c7 100644
--- a/src/lib/io.rs
+++ b/src/lib/io.rs
@@ -91,6 +91,7 @@ tag fileflag {
truncate;
}
+// FIXME move into fd_buf_writer
fn writefd(int fd, vec[u8] v) {
auto len = _vec.len[u8](v);
auto count = 0u;
@@ -107,19 +108,17 @@ fn writefd(int fd, vec[u8] v) {
}
}
-fn new_buf_writer(str path, vec[fileflag] flags) -> buf_writer {
-
- state obj fd_buf_writer(int fd) {
-
- fn write(vec[u8] v) {
- writefd(fd, v);
- }
+state obj fd_buf_writer(int fd, bool must_close) {
+ fn write(vec[u8] v) {
+ writefd(fd, v);
+ }
- drop {
- os.libc.close(fd);
- }
+ drop {
+ if (must_close) {os.libc.close(fd);}
}
+}
+fn file_buf_writer(str path, vec[fileflag] flags) -> buf_writer {
let int fflags =
os.libc_constants.O_WRONLY() |
os.libc_constants.O_BINARY();
@@ -142,26 +141,52 @@ fn new_buf_writer(str path, vec[fileflag] flags) -> buf_writer {
log sys.rustrt.last_os_error();
fail;
}
- ret fd_buf_writer(fd);
+ ret fd_buf_writer(fd, true);
}
type writer =
state obj {
- fn write_str(str s);
- fn write_int(int n);
- fn write_uint(uint n);
+ impure fn write_str(str s);
+ impure fn write_int(int n);
+ impure fn write_uint(uint n);
};
-fn file_writer(str path,
- vec[fileflag] flags)
- -> writer
-{
- state obj fw(buf_writer out) {
- fn write_str(str s) { out.write(_str.bytes(s)); }
- fn write_int(int n) { out.write(_str.bytes(_int.to_str(n, 10u))); }
- fn write_uint(uint n) { out.write(_str.bytes(_uint.to_str(n, 10u))); }
+state obj new_writer(buf_writer out) {
+ impure fn write_str(str s) { out.write(_str.bytes(s)); }
+ impure fn write_int(int n) { out.write(_str.bytes(_int.to_str(n, 10u))); }
+ impure fn write_uint(uint n) { out.write(_str.bytes(_uint.to_str(n, 10u))); }
+}
+
+fn file_writer(str path, vec[fileflag] flags) -> writer {
+ ret new_writer(file_buf_writer(path, flags));
+}
+
+// FIXME it would be great if this could be a const named stdout
+fn stdout_writer() -> writer {
+ ret new_writer(fd_buf_writer(1, false));
+}
+
+type str_writer =
+ state obj {
+ fn get_writer() -> writer;
+ fn get_str() -> str;
+ };
+
+type str_buf = @rec(mutable str buf);
+
+// TODO awkward! it's not possible to implement a writer with an extra method
+fn string_writer() -> str_writer {
+ auto buf = @rec(mutable buf = "");
+ state obj str_writer_writer(str_buf buf) {
+ impure fn write_str(str s) { buf.buf += s; }
+ impure fn write_int(int n) { buf.buf += _int.to_str(n, 10u); }
+ impure fn write_uint(uint n) { buf.buf += _uint.to_str(n, 10u); }
+ }
+ state obj str_writer_wrap(writer wr, str_buf buf) {
+ fn get_writer() -> writer {ret wr;}
+ fn get_str() -> str {ret buf.buf;}
}
- ret fw(new_buf_writer(path, flags));
+ ret str_writer_wrap(str_writer_writer(buf), buf);
}
//