@shd101wyy/yo 0.1.21 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,138 @@
1
+ //! Mutable UTF-8 string builder for efficient incremental construction.
2
+
3
+ { ArrayList } :: import "../collections/array_list.yo";
4
+ { String } :: import "./string.yo";
5
+
6
+ /**
7
+ * Mutable buffer for building a `String` incrementally.
8
+ *
9
+ * Use `StringBuilder` when you need to construct a string from many parts,
10
+ * appending bytes or strings in a loop, before converting to an immutable
11
+ * `String` with `to_string()`.
12
+ *
13
+ * ## Example
14
+ * ```rust
15
+ * sb := StringBuilder.new();
16
+ * sb.write_str("Hello");
17
+ * sb.write_str(", ");
18
+ * sb.write_string(`world`);
19
+ * sb.write_byte(u8(33)); // '!'
20
+ * result := sb.to_string();
21
+ * assert(result == `Hello, world!`, "built string");
22
+ * ```
23
+ */
24
+ StringBuilder :: object(
25
+ _buf : ArrayList(u8)
26
+ );
27
+
28
+ impl(StringBuilder,
29
+ /**
30
+ * Create a new, empty `StringBuilder`.
31
+ */
32
+ new : (fn() -> Self)(
33
+ Self(_buf: ArrayList(u8).new())
34
+ ),
35
+
36
+ /**
37
+ * Create a `StringBuilder` pre-allocated for `capacity` bytes.
38
+ */
39
+ with_capacity : (fn(capacity: usize) -> Self)(
40
+ Self(_buf: ArrayList(u8).with_capacity(capacity))
41
+ ),
42
+
43
+ /**
44
+ * Returns the current number of bytes in the buffer.
45
+ */
46
+ len : (fn(self: *(Self)) -> usize)(
47
+ self._buf.len()
48
+ ),
49
+
50
+ /**
51
+ * Returns true if the buffer is empty.
52
+ */
53
+ is_empty : (fn(self: *(Self)) -> bool)(
54
+ (self._buf.len() == usize(0))
55
+ ),
56
+
57
+ /**
58
+ * Append a `str` (raw byte slice) to the buffer.
59
+ */
60
+ write_str : (fn(self: *(Self), s: str) -> unit)({
61
+ byte_len := s.len();
62
+ if((byte_len > usize(0)), {
63
+ self._buf.extend_from_ptr(s.ptr(), byte_len);
64
+ });
65
+ }),
66
+
67
+ /**
68
+ * Append a `String` to the buffer.
69
+ */
70
+ write_string : (fn(self: *(Self), s: String) -> unit)(
71
+ match(s._bytes,
72
+ .None => (),
73
+ .Some(al) => {
74
+ i := usize(0);
75
+ n := al.len();
76
+ while ((i < n)),
77
+ (i = (i + usize(1))),
78
+ {
79
+ byte_opt := al.get(i);
80
+ match(byte_opt,
81
+ .Some(b) => { self._buf.push(b); },
82
+ .None => ()
83
+ );
84
+ };
85
+ }
86
+ )
87
+ ),
88
+
89
+ /**
90
+ * Append a single byte to the buffer.
91
+ */
92
+ write_byte : (fn(self: *(Self), b: u8) -> unit)({
93
+ self._buf.push(b);
94
+ }),
95
+
96
+ /**
97
+ * Append a `String` followed by a newline byte (`\n`).
98
+ */
99
+ write_line : (fn(self: *(Self), s: String) -> unit)({
100
+ self.write_string(s);
101
+ self._buf.push(u8(10));
102
+ }),
103
+
104
+ /**
105
+ * Consume the builder and return the accumulated `String`.
106
+ * The builder is left empty after this call.
107
+ */
108
+ to_string : (fn(self: *(Self)) -> String)({
109
+ n := self._buf.len();
110
+ cond(
111
+ (n == usize(0)) => String(_bytes: .None),
112
+ true => {
113
+ buf := ArrayList(u8).with_capacity(n);
114
+ i := usize(0);
115
+ while ((i < n)),
116
+ (i = (i + usize(1))),
117
+ {
118
+ byte_opt := self._buf.get(i);
119
+ match(byte_opt,
120
+ .Some(b) => { buf.push(b); },
121
+ .None => ()
122
+ );
123
+ };
124
+ self._buf = ArrayList(u8).new();
125
+ String(_bytes: .Some(buf))
126
+ }
127
+ )
128
+ }),
129
+
130
+ /**
131
+ * Clear the buffer without freeing memory.
132
+ */
133
+ clear : (fn(self: *(Self)) -> unit)({
134
+ self._buf = ArrayList(u8).new();
135
+ })
136
+ );
137
+
138
+ export StringBuilder;