• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moonbitlang / x / 662

24 Oct 2025 12:39PM UTC coverage: 90.327% (-0.04%) from 90.368%
662

push

github

web-flow
refactor json5 using lexmatch (#198)

* refactor: use lexmatch to lex number literal

* refactor: use range pattern

* moon info

30 of 34 new or added lines in 3 files covered. (88.24%)

6 existing lines in 2 files now uncovered.

1989 of 2202 relevant lines covered (90.33%)

397.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.51
/encoding/encoding.mbt
1
// Copyright 2025 International Digital Economy Academy
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
///|
16
/// Encode a given string to the specified character encoding and returns the resulting bytes.
17
///
18
/// # Parameters
19
///
20
/// - `encoding` : The target encoding format.
21
/// - `src`: The input string to be encoded.
22
///
23
/// # Returns
24
///
25
/// A `bytes` representing the encoded string in the selected format.
26
///
27
/// # Examples
28
///
29
/// ```moonbit
30
///   let src = "Hello, World!"
31
///   let encoded_bytes = encode(UTF8, src)
32
///   assert_eq(encoded_bytes, @bytes.of([72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33]))
33
/// ```
34
pub fn encode(encoding : Encoding, src : String) -> Bytes {
35
  // NOTE: special case: MoonBit String are already valid UTF16(LE) bytes
36
  match encoding {
50✔
37
    UTF16 | UTF16LE => {
44✔
38
      let arr = FixedArray::make(src.length() * 2, b'\x00')
44✔
39
      arr.blit_from_string(0, src, 0, src.length())
44✔
40
      return arr.unsafe_reinterpret_as_bytes()
44✔
41
    }
42
    _ => ()
6✔
43
  }
44
  let new_buf = @buffer.new(size_hint=src.length() * 4)
6✔
45
  let write = match encoding {
6✔
46
    UTF8 => write_utf8_char
4✔
47
    UTF16BE => write_utf16be_char
2✔
UNCOV
48
    _ => abort("unreachable")
×
49
  }
50
  for char in src {
51
    // SAFETY: Assume String are always valid UTF16LE
52
    write(new_buf, char)
104✔
53
  }
54
  new_buf.to_bytes()
6✔
55
}
56

57
///|
58
/// Encodes a string into the specified character encoding and writes the result
59
/// directly into a buffer.
60
///
61
/// Parameters:
62
///
63
/// * `string` : The input string to be encoded.
64
/// * `buffer` : The buffer where the encoded bytes will be written to.
65
/// * `encoding` : The target encoding format. Defaults to UTF8 if not specified.
66
///
67
/// Example:
68
///
69
/// ```moonbit
70
///   let buf = @buffer.new()
71
///   let text = "Hello, world"
72
///   @encoding.encode_to(text, buf, encoding=UTF16)
73
///   inspect(buf.to_string(), content="Hello, world")
74
/// ```
75
pub fn encode_to(
76
  src : String,
77
  buffer : @buffer.Buffer,
78
  encoding~ : Encoding,
79
) -> Unit {
80
  match encoding {
5✔
81
    UTF8 =>
82
      for char in src {
1✔
83
        write_utf8_char(buffer, char)
3✔
84
      }
85
    UTF16BE =>
86
      for char in src {
1✔
87
        write_utf16be_char(buffer, char)
25✔
88
      }
89
    UTF16 | UTF16LE => buffer.write_string(src)
3✔
90
  }
91
}
92

93
///|
94
/// Converts a Char to UTF-8 bytes.
95
///
96
/// Note that this function incurs allocation overhead
97
/// due to the intermediate creation of new buffers.
98
pub fn to_utf8_bytes(value : Char) -> Bytes {
99
  let buf = @buffer.new(size_hint=4)
5✔
100
  write_utf8_char(buf, value)
5✔
101
  buf.to_bytes()
5✔
102
}
103

104
///|
105
/// Converts a Char to UTF-16LE bytes.
106
///
107
/// Alias for `to_utf16le_bytes`.
108
///
109
/// Note that this function incurs allocation overhead
110
/// due to the intermediate creation of new buffers.
111
pub fn to_utf16_bytes(value : Char) -> Bytes {
112
  to_utf16le_bytes(value)
4✔
113
}
114

115
///|
116
/// Converts a Char to UTF-16LE bytes.
117
///
118
/// Note that this function incurs allocation overhead
119
/// due to the intermediate creation of new buffers.
120
pub fn to_utf16le_bytes(value : Char) -> Bytes {
121
  let buf = @buffer.new(size_hint=4)
8✔
122
  write_utf16le_char(buf, value)
8✔
123
  buf.to_bytes()
8✔
124
}
125

126
///|
127
/// Converts a Char to UTF-16BE bytes.
128
///
129
/// Note that this function incurs allocation overhead
130
/// due to the intermediate creation of new buffers.
131
pub fn to_utf16be_bytes(value : Char) -> Bytes {
132
  let buf = @buffer.new(size_hint=4)
4✔
133
  write_utf16be_char(buf, value)
4✔
134
  buf.to_bytes()
4✔
135
}
136

137
///|
138
/// Write a char into buffer as UTF8.
139
pub fn write_utf8_char(buf : @buffer.Buffer, value : Char) -> Unit {
140
  let code = value.to_uint()
87✔
141
  match code {
87✔
142
    _..<0x80 => {
33✔
143
      let b0 = ((code & 0x7F) | 0x00).to_byte()
33✔
144
      buf.write_byte(b0)
33✔
145
    }
146
    _..<0x0800 => {
2✔
147
      let b0 = (((code >> 6) & 0x1F) | 0xC0).to_byte()
2✔
148
      let b1 = ((code & 0x3F) | 0x80).to_byte()
2✔
149
      buf.write_byte(b0)
2✔
150
      buf.write_byte(b1)
2✔
151
    }
152
    _..<0x010000 => {
31✔
153
      let b0 = (((code >> 12) & 0x0F) | 0xE0).to_byte()
31✔
154
      let b1 = (((code >> 6) & 0x3F) | 0x80).to_byte()
31✔
155
      let b2 = ((code & 0x3F) | 0x80).to_byte()
31✔
156
      buf.write_byte(b0)
31✔
157
      buf.write_byte(b1)
31✔
158
      buf.write_byte(b2)
31✔
159
    }
160
    _..<0x110000 => {
21✔
161
      let b0 = (((code >> 18) & 0x07) | 0xF0).to_byte()
21✔
162
      let b1 = (((code >> 12) & 0x3F) | 0x80).to_byte()
21✔
163
      let b2 = (((code >> 6) & 0x3F) | 0x80).to_byte()
21✔
164
      let b3 = ((code & 0x3F) | 0x80).to_byte()
21✔
165
      buf.write_byte(b0)
21✔
166
      buf.write_byte(b1)
21✔
167
      buf.write_byte(b2)
21✔
168
      buf.write_byte(b3)
21✔
169
    }
UNCOV
170
    _ => abort("Char out of range")
×
171
  }
172
}
173

174
///|
175
/// Write a char into buffer as UTF16LE.
176
/// Alias for `write_utf16le_char`
177
pub fn write_utf16_char(buf : @buffer.Buffer, value : Char) -> Unit {
178
  write_utf16le_char(buf, value)
4✔
179
}
180

181
///|
182
/// Write a char into buffer as UTF16LE.
183
pub fn write_utf16le_char(buf : @buffer.Buffer, value : Char) -> Unit {
184
  let code = value.to_uint()
64✔
185
  if code < 0x10000 {
186
    let b0 = (code & 0xFF).to_byte()
44✔
187
    let b1 = (code >> 8).to_byte()
44✔
188
    buf.write_byte(b0)
44✔
189
    buf.write_byte(b1)
44✔
190
  } else if code < 0x110000 {
20✔
191
    let hi = code - 0x10000
20✔
192
    let lo = (hi >> 10) | 0xD800
193
    let hi = (hi & 0x3FF) | 0xDC00
194
    let b0 = (lo & 0xFF).to_byte()
20✔
195
    let b1 = (lo >> 8).to_byte()
20✔
196
    let b2 = (hi & 0xFF).to_byte()
20✔
197
    let b3 = (hi >> 8).to_byte()
20✔
198
    buf.write_byte(b0)
20✔
199
    buf.write_byte(b1)
20✔
200
    buf.write_byte(b2)
20✔
201
    buf.write_byte(b3)
20✔
202
  } else {
UNCOV
203
    abort("Char out of range")
×
204
  }
205
}
206

207
///|
208
/// Write a char into buffer as UTF16BE.
209
pub fn write_utf16be_char(buf : @buffer.Buffer, value : Char) -> Unit {
210
  let code = value.to_uint()
116✔
211
  if code < 0x10000 {
212
    let b0 = (code >> 8).to_byte()
106✔
213
    let b1 = (code & 0xFF).to_byte()
106✔
214
    buf.write_byte(b0)
106✔
215
    buf.write_byte(b1)
106✔
216
  } else if code < 0x110000 {
10✔
217
    let hi = code - 0x10000
10✔
218
    let lo = (hi >> 10) | 0xD800
219
    let hi = (hi & 0x3FF) | 0xDC00
220
    let b0 = (lo >> 8).to_byte()
10✔
221
    let b1 = (lo & 0xFF).to_byte()
10✔
222
    let b2 = (hi >> 8).to_byte()
10✔
223
    let b3 = (hi & 0xFF).to_byte()
10✔
224
    buf.write_byte(b0)
10✔
225
    buf.write_byte(b1)
10✔
226
    buf.write_byte(b2)
10✔
227
    buf.write_byte(b3)
10✔
228
  } else {
UNCOV
229
    abort("Char out of range")
×
230
  }
231
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc