diff --git a/builtin/bytesview.mbt b/builtin/bytesview.mbt index cdb496fef..f67d749b8 100644 --- a/builtin/bytesview.mbt +++ b/builtin/bytesview.mbt @@ -346,8 +346,10 @@ fn write_byte_hex(logger : &Logger, byte : Byte) -> Unit { } ///| -pub impl Show for BytesView with fn output(self, logger) { - logger.write_string("b\"") +/// Writes the bytes with printable ASCII kept as-is and everything else +/// rendered as `\xHH`, without the surrounding `b"`/`"`. Shared by `Show`, +/// which adds the quotes, and `ToJson`, which does not. +pub fn BytesView::escape_to(self : BytesView, logger : &Logger) -> Unit { for byte in self { if byte is (b' '..=b'~') && byte != b'"' && byte != b'\\' { logger.write_char(byte.to_char()) @@ -356,7 +358,11 @@ pub impl Show for BytesView with fn output(self, logger) { write_byte_hex(logger, byte) } } - logger.write_string("\"") +} + +///| +pub impl Show for BytesView with fn output(self, logger) { + logger <+ "b\"\{l => self.escape_to(l)}\"" } ///| @@ -593,14 +599,7 @@ pub fn BytesView::to_owned(self : BytesView) -> Bytes { ///| pub impl ToJson for BytesView with fn to_json(self) -> Json { let sb = StringBuilder() - for byte in self { - if byte is (b' '..=b'~') && byte != b'"' && byte != b'\\' { - sb.write_char(byte.to_char()) - } else { - sb.write_string("\\x") - write_byte_hex(sb, byte) - } - } + self.escape_to(sb) Json::string(sb.to_string()) } diff --git a/builtin/char.mbt b/builtin/char.mbt index 964fd6db4..41d32ec16 100644 --- a/builtin/char.mbt +++ b/builtin/char.mbt @@ -504,9 +504,7 @@ fn Char::escape_to(self : Char, logger : &Logger, quote? : Bool = true) -> Unit ' '..='~' => logger.write_char(self) _ => if !self.is_printable() { - logger.write_string("\\u{") - logger.write_string(self.to_hex()) - logger.write_char('}') + logger <+ "\\u{\{l => l.write_string(self.to_hex())}}" } else { logger.write_char(self) } diff --git a/builtin/console.mbt b/builtin/console.mbt index 941515684..745a0ec11 100644 --- a/builtin/console.mbt +++ b/builtin/console.mbt @@ -81,8 +81,7 @@ fn base64_encode(data : FixedArray[Byte]) -> String { let x1 = base64[(b0 & 0x03) << 4] buf.write_char(x0.to_char()) buf.write_char(x1.to_char()) - buf.write_char('=') - buf.write_char('=') + buf <+ "==" } else if rem == 2 { let b0 = data[len - 2].to_int() let b1 = data[len - 1].to_int() diff --git a/builtin/fixedarray.mbt b/builtin/fixedarray.mbt index 4a8e2af2e..2403f31a3 100644 --- a/builtin/fixedarray.mbt +++ b/builtin/fixedarray.mbt @@ -1397,8 +1397,7 @@ test "iter" { let exb = StringBuilder() let mut i = 0 iter.each(x => { - exb.write_string(x.to_string()) - exb.write_char('\n') + exb <+ "\{x}\n" i += 1 }) assert_true(i == arr.length()) diff --git a/builtin/iterator.mbt b/builtin/iterator.mbt index 8238c8f53..9e6dac957 100644 --- a/builtin/iterator.mbt +++ b/builtin/iterator.mbt @@ -63,15 +63,14 @@ pub impl[X : Show] Show for Iter[X] ///| pub impl[X : Show] Show for Iter[X] with fn output(self, logger) { - logger.write_string("[") + logger <+ "[" if self.next() is Some(x) { logger.write_object(x) while self.next() is Some(x) { - logger.write_string(", ") - logger.write_object(x) + logger <+ ", \{l => l.write_object(x)}" } } - logger.write_string("]") + logger <+ "]" } ///| diff --git a/builtin/linked_hash_map.mbt b/builtin/linked_hash_map.mbt index f61828f2b..e818bb733 100644 --- a/builtin/linked_hash_map.mbt +++ b/builtin/linked_hash_map.mbt @@ -669,17 +669,15 @@ pub impl[K : Show, V : Show] Show for Map[K, V] ///| pub impl[K : Show, V : Show] Show for Map[K, V] with fn output(self, logger) { - logger.write_string("{") + logger <+ "{" for x = 0, y = self.head { match (x, y) { - (_, None) => break logger.write_string("}") + (_, None) => break logger <+ "}" (i, Some({ key, value, next, .. })) => { if i > 0 { - logger.write_string(", ") + logger <+ ", " } - logger.write_object(key) - logger.write_string(": ") - logger.write_object(value) + logger <+ "\{l => l.write_object(key)}: \{l => l.write_object(value)}" continue i + 1, next } } diff --git a/builtin/pkg.generated.mbti b/builtin/pkg.generated.mbti index ff222a722..e0013d42d 100644 --- a/builtin/pkg.generated.mbti +++ b/builtin/pkg.generated.mbti @@ -1170,6 +1170,7 @@ pub fn BytesView::compare(Self, Self) -> Int pub fn BytesView::data(Self) -> Bytes pub fn BytesView::equal(Self, Self) -> Bool pub fn BytesView::equal_to_bytes(Self, Bytes) -> Bool +pub fn BytesView::escape_to(Self, &Logger) -> Unit pub fn BytesView::find(Self, Self) -> Int? pub fn BytesView::get(Self, Int) -> Byte? pub fn BytesView::get_view(Self, start? : Int, end? : Int) -> Self? diff --git a/builtin/show.mbt b/builtin/show.mbt index 9e091f9d2..6abc0a296 100644 --- a/builtin/show.mbt +++ b/builtin/show.mbt @@ -191,9 +191,7 @@ fn StringView::escape_to( code => if code < ' ' { flush_segment(seg, i) - logger.write_string("\\u{") - logger.write_string(code.to_byte().to_hex()) - logger.write_char('}') + logger <+ "\\u{\{l => l.write_string(code.to_byte().to_hex())}}" continue i + 1, i + 1 } else { continue i + 1, seg diff --git a/diff/hunk.mbt b/diff/hunk.mbt index 56a64c266..ce570ec3b 100644 --- a/diff/hunk.mbt +++ b/diff/hunk.mbt @@ -20,15 +20,13 @@ impl Show for Range with fn output(self, logger) { let mut beginning = self.0 + 1 // from array index to line number let len = self.1 - self.0 if len == 1 { - logger.write_string(beginning.to_string()) + logger.write_object(beginning) } else { if len == 0 { // empty ranges begin at line just before the range beginning -= 1 } - logger.write_string(beginning.to_string()) - logger.write_char(',') - logger.write_string(len.to_string()) + logger <+ "\{l => l.write_object(beginning)},\{l => l.write_object(len)}" } } @@ -67,7 +65,7 @@ fn HunkHeader::new(edits : ArrayView[Edit]) -> Self { ///| impl Show for HunkHeader with fn output(self, logger) { - logger.write_string("@@ -\{self.0} +\{self.1} @@") + logger <+ "@@ -\{self.0} +\{self.1} @@" } ///| diff --git a/hashmap/utils.mbt b/hashmap/utils.mbt index 3ecd385e1..02da14a68 100644 --- a/hashmap/utils.mbt +++ b/hashmap/utils.mbt @@ -337,18 +337,14 @@ pub impl[K : Show, V : Show] Show for HashMap[K, V] ///| pub impl[K : Show, V : Show] Show for HashMap[K, V] with fn output(self, logger) { - logger.write_string("HashMap::from_array([") + logger <+ "HashMap::from_array([" self.eachi((i, k, v) => { if i > 0 { - logger.write_string(", ") + logger <+ ", " } - logger.write_string("(") - logger.write_object(k) - logger.write_string(", ") - logger.write_object(v) - logger.write_string(")") + logger <+ "(\{l => l.write_object(k)}, \{l => l.write_object(v)})" }) - logger.write_string("])") + logger <+ "])" } ///| diff --git a/json/json_path.mbt b/json/json_path.mbt index 06ca70746..adfd6a209 100644 --- a/json/json_path.mbt +++ b/json/json_path.mbt @@ -49,8 +49,8 @@ pub impl Show for JsonPath with fn output(self, logger) { } for ch in token.iter() { match ch { - '~' => logger.write_string("~0") - '/' => logger.write_string("~1") + '~' => logger <+ "~0" + '/' => logger <+ "~1" _ => logger.write_char(ch) } } @@ -60,16 +60,10 @@ pub impl Show for JsonPath with fn output(self, logger) { fn build_path(path : JsonPath, logger : &Logger) -> Unit { match path { Root => () - Key(parent, key~) => { - build_path(parent, logger) - logger.write_char('/') - write_token(logger, key) - } - Index(parent, index~) => { - build_path(parent, logger) - logger.write_char('/') - logger.write_object(index) - } + Key(parent, key~) => + logger <+ "\{l => build_path(parent, l)}/\{l => write_token(l, key)}" + Index(parent, index~) => + logger <+ "\{l => build_path(parent, l)}/\{l => l.write_object(index)}" } } diff --git a/json/types.mbt b/json/types.mbt index 0a4750f4c..f518fd328 100644 --- a/json/types.mbt +++ b/json/types.mbt @@ -35,7 +35,7 @@ pub impl Show for ParseError with fn output(self, logger) { InvalidChar({ line, column, }, c) => logger <+ $|Invalid character \{c.escape()} at line \{line}, column \{column} - InvalidEof => logger.write_string("Unexpected end of file") + InvalidEof => logger <+ "Unexpected end of file" InvalidNumber({ line, column, }, s) => logger <+ $|Invalid number \{s} at line \{line}, column \{column} @@ -43,9 +43,8 @@ pub impl Show for ParseError with fn output(self, logger) { logger <+ $|Invalid escape sequence in identifier at line \{line}, column \{column} DepthLimitExceeded => - logger.write_string( - "Depth limit exceeded, please increase the max_nesting_depth parameter", - ) + logger <+ + $|Depth limit exceeded, please increase the max_nesting_depth parameter } } @@ -57,34 +56,18 @@ pub impl Show for Json #warnings("-deprecated") pub impl Show for Json with fn output(self, logger) { match self { - Null => logger.write_string("Null") - True => logger.write_string("True") - False => logger.write_string("False") + Null => logger <+ "Null" + True => logger <+ "True" + False => logger <+ "False" Number(n, repr~) => { - logger.write_string("Number(") - Show::output(n, logger) + logger <+ "Number(\{l => Show::output(n, l)}" if repr is Some(repr) { - logger.write_string(", repr=") - logger.write_string("Some(") - Show::output(repr, logger) - logger.write_string(")") + logger <+ ", repr=Some(\{l => Show::output(repr, l)})" } - logger.write_string(")") - } - String(s) => { - logger.write_string("String(") - Show::output(s, logger) - logger.write_string(")") - } - Array(a) => { - logger.write_string("Array(") - Show::output(a, logger) - logger.write_string(")") - } - Object(o) => { - logger.write_string("Object(") - Show::output(o, logger) - logger.write_string(")") + logger <+ ")" } + String(s) => logger <+ "String(\{l => Show::output(s, l)})" + Array(a) => logger <+ "Array(\{l => Show::output(a, l)})" + Object(o) => logger <+ "Object(\{l => Show::output(o, l)})" } } diff --git a/set/linked_hash_set.mbt b/set/linked_hash_set.mbt index 234152cc8..331491da6 100644 --- a/set/linked_hash_set.mbt +++ b/set/linked_hash_set.mbt @@ -468,13 +468,13 @@ pub impl[K : Show] Show for Set[K] ///| pub impl[K : Show] Show for Set[K] with fn output(self, logger) { - logger.write_string("{") + logger <+ "{" for i = 0, curr = self.head { match (i, curr) { - (_, None) => break logger.write_string("}") + (_, None) => break logger <+ "}" (i, Some({ key, next, .. })) => { if i > 0 { - logger.write_string(", ") + logger <+ ", " } logger.write_object(key) continue i + 1, next diff --git a/v128/simd_basic.mbt b/v128/simd_basic.mbt index 8431be082..a88d8a6f8 100644 --- a/v128/simd_basic.mbt +++ b/v128/simd_basic.mbt @@ -29,14 +29,19 @@ pub impl Eq for V128 with fn not_equal(self : V128, other : V128) -> Bool { } ///| -fn u64_hex(value : UInt64) -> String { +fn u64_hex_to(logger : &Logger, value : UInt64) -> Unit { let digits = value.to_string(radix=16) - let buf = StringBuilder() - buf.write_string("0x") + logger <+ "0x" for _ in digits.length()..<16 { - buf.write_char('0') + logger.write_char('0') } - buf.write_string(digits) + logger.write_string(digits) +} + +///| +fn u64_hex(value : UInt64) -> String { + let buf = StringBuilder() + u64_hex_to(buf, value) buf.to_string() } @@ -46,11 +51,8 @@ fn u64_hex(value : UInt64) -> String { #internal(experimental, "subject to breaking change without notice") #doc(hidden) pub impl Show for V128 with fn output(self : V128, logger) { - logger.write_string("V128(") - logger.write_string(u64_hex(lo(self))) - logger.write_string(", ") - logger.write_string(u64_hex(hi(self))) - logger.write_string(")") + logger <+ + "V128(\{l => u64_hex_to(l, lo(self))}, \{l => u64_hex_to(l, hi(self))})" } ///|