mirror of https://github.com/Wilfred/difftastic/
111 lines
2.7 KiB
Plaintext
111 lines
2.7 KiB
Plaintext
use encoding::utf8;
|
|
use io;
|
|
use strings;
|
|
|
|
// Appends zero or more strings to an [io::stream]. The stream needn't be a
|
|
// strio stream, but it's often efficient if it is. Returns the number of bytes
|
|
// written, or an error.
|
|
export fn concat(st: *io::stream, strs: str...) (size | io::error) = {
|
|
let n = 0z;
|
|
for (let i = 0z; i < len(strs); i += 1) {
|
|
let q = 0z;
|
|
let buf = strings::toutf8(strs[i]);
|
|
for (q < len(buf)) {
|
|
let w = io::write(st, buf[q..])?;
|
|
n += w;
|
|
q -= w;
|
|
};
|
|
};
|
|
return n;
|
|
};
|
|
|
|
@test fn concat() void = {
|
|
let st = dynamic();
|
|
defer io::close(st);
|
|
concat(st, "hello") as size;
|
|
concat(st, " ", "world") as size;
|
|
assert(string(st) == "hello world");
|
|
};
|
|
|
|
// Joins several strings together by a delimiter and writes them to a stream.
|
|
// The stream needn't be a strio stream, but it's often more efficient if it is.
|
|
// Returns the number of bytes written, or an error.
|
|
export fn join(st: *io::stream, delim: str, strs: str...) (size | io::error) = {
|
|
let n = 0z;
|
|
let delim = strings::toutf8(delim);
|
|
for (let i = 0z; i < len(strs); i += 1) {
|
|
let q = 0z;
|
|
let buf = strings::toutf8(strs[i]);
|
|
for (q < len(buf)) {
|
|
let w = io::write(st, buf[q..])?;
|
|
n += w;
|
|
q -= w;
|
|
};
|
|
if (i + 1 < len(strs)) {
|
|
let q = 0z;
|
|
for (q < len(delim)) {
|
|
let w = io::write(st, delim[q..])?;
|
|
n += w;
|
|
q -= w;
|
|
};
|
|
};
|
|
};
|
|
return n;
|
|
};
|
|
|
|
@test fn join() void = {
|
|
let st = dynamic();
|
|
defer io::close(st);
|
|
join(st, "::", "hello", "world") as size;
|
|
assert(string(st) == "hello::world");
|
|
truncate(st);
|
|
join(st, "::") as size;
|
|
assert(string(st) == "");
|
|
truncate(st);
|
|
join(st, "::", "foo") as size;
|
|
assert(string(st) == "foo");
|
|
};
|
|
|
|
// Joins several strings together by a delimiter and writes them to a stream, in
|
|
// reverse order. The stream needn't be a strio stream, but it's often more
|
|
// efficient if it is. Returns the number of bytes written, or an error.
|
|
export fn rjoin(st: *io::stream, delim: str, strs: str...) (size | io::error) = {
|
|
let n = 0z;
|
|
let delim = strings::toutf8(delim);
|
|
for (let i = len(strs); i > 0; i -= 1) {
|
|
let q = 0z;
|
|
let buf = strings::toutf8(strs[i - 1]);
|
|
for (q < len(buf)) {
|
|
let w = io::write(st, buf[q..])?;
|
|
n += w;
|
|
q -= w;
|
|
};
|
|
if (i - 1 > 0) {
|
|
let q = 0z;
|
|
for (q < len(delim)) {
|
|
let w = io::write(st, delim[q..])?;
|
|
n += w;
|
|
q -= w;
|
|
};
|
|
};
|
|
};
|
|
return n;
|
|
};
|
|
|
|
@test fn rjoin() void = {
|
|
let st = dynamic();
|
|
defer io::close(st);
|
|
rjoin(st, "::", "hello", "world") as size;
|
|
assert(string(st) == "world::hello");
|
|
truncate(st);
|
|
rjoin(st, "::") as size;
|
|
assert(string(st) == "");
|
|
truncate(st);
|
|
rjoin(st, "::", "foo") as size;
|
|
assert(string(st) == "foo");
|
|
};
|
|
|
|
// Appends a rune to a stream.
|
|
export fn appendrune(st: *io::stream, r: rune) (size | io::error) =
|
|
io::write(st, utf8::encoderune(r));
|