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

moonbitlang / x / 830

01 Jun 2026 03:30AM UTC coverage: 87.075% (+0.1%) from 86.942%
830

Pull #250

github

web-flow
Merge 939f9fd3f into ced18cb1c
Pull Request #250: [codex] Add Debug support for common types

7 of 7 new or added lines in 2 files covered. (100.0%)

52 existing lines in 9 files now uncovered.

2358 of 2708 relevant lines covered (87.08%)

338.53 hits per line

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

93.88
/stack/stack.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
/// Create an empty stack.
17
///
18
/// # Example
19
///
20
/// ```
21
/// let s : Stack[Int] = @stack.Stack::new()
22
/// assert_true(s.is_empty())
23
/// let s1 : Stack[Int] = @stack.new()
24
/// assert_true(s1.is_empty())
25
/// ```
26
#as_free_fn
27
pub fn[T] Stack::new() -> Stack[T] {
28
  { elements: @list.List::new(), len: 0 }
13✔
29
}
30

31
///|
32
test "new" {
33
  let s : Stack[Int] = new()
34
  inspect(s, content="Stack::[]")
35
}
36

37
///|
38
/// Create a stack based on all elements in array.
39
///
40
/// # Example
41
///
42
/// ```
43
///   let s = Stack::from_array([1, 2, 3])
44
///   assert_eq(s.length(), 3)
45
/// ```
46
pub fn[T] Stack::from_array(array : Array[T]) -> Stack[T] {
47
  { elements: @list.from_array(array), len: array.length() }
3✔
48
}
49

50
///|
51
test "from_array" {
52
  let s = Stack::from_array([1, 2, 3])
53
  inspect(s, content="Stack::[1, 2, 3]")
54
  inspect(s.len, content="3")
55
}
56

57
///|
58
pub fn[T] Stack::from_iter(iter : Iter[T]) -> Stack[T] {
59
  let mut len = 0
1✔
60
  let elements = @list.from_iter(iter.tap(_ => len += 1))
1✔
61
  { elements, len }
62
}
63

64
///|
65
test "from_iter" {
66
  let s = Stack::from_iter([1, 2, 3].iter())
67
  inspect(s, content="Stack::[1, 2, 3]")
68
  inspect(s.len, content="3")
69
}
70

71
///|
72
/// Create a stack based on all elements in array.
73
///
74
/// # Example
75
///
76
/// ```
77
/// let s = of([1, 2, 3])
78
/// assert_eq(s.length(), 3)
79
/// ```
80
#as_free_fn
81
pub fn[T] Stack::of(array : FixedArray[T]) -> Stack[T] {
82
  { elements: @list.from_array(array), len: array.length() }
27✔
83
}
84

85
///|
86
test "of" {
87
  let s = of([1, 2, 3])
88
  inspect(s, content="Stack::[1, 2, 3]")
89
}
90

91
///|
92
pub impl[T : Show] Show for Stack[T] with fn output(self, logger : &Logger) -> Unit {
93
  logger.write_string("Stack::[")
23✔
94
  let mut i = 0
95
  self.elements.each(fn(t) {
23✔
96
    if i > 0 {
43✔
97
      logger.write_string(", ")
27✔
98
    }
99
    t.output(logger)
43✔
100
    i = i + 1
101
  })
102
  logger.write_string("]")
23✔
103
}
104

105
///|
106
pub impl[T : Debug] Debug for Stack[T] with fn to_repr(self : Stack[T]) -> Repr {
107
  let buf = StringBuilder::new(size_hint=0)
2✔
108
  buf.write_string("Stack::[")
2✔
109
  let mut i = 0
110
  self.elements.each(fn(t) {
2✔
111
    if i > 0 {
5✔
112
      buf.write_string(", ")
3✔
113
    }
114
    buf.write_string(t.to_repr().to_string())
5✔
115
    i += 1
116
  })
117
  buf.write_string("]")
2✔
118
  Repr::literal(buf.to_string())
2✔
119
}
120

121
///|
122
test "to_string" {
123
  let empty : Stack[Int] = new()
124
  inspect(empty, content="Stack::[]")
125
  inspect(of([1, 2, 3, 4, 5]), content="Stack::[1, 2, 3, 4, 5]")
126
}
127

128
///|
129
/// Create a stack based on another stack.
130
///
131
/// # Example
132
///
133
/// ```
134
///   let s = @stack.of([1, 2, 3])
135
///   let s1 = Stack::from_stack(s)
136
///   assert_eq(s1.length(), 3)
137
/// ```
138
pub fn[T] Stack::from_stack(other : Stack[T]) -> Stack[T] {
139
  { ..other }
1✔
140
}
141

142
///|
143
test "from_stack" {
144
  let s = of([1, 2, 3])
145
  let s1 = Stack::from_stack(s)
146
  inspect(s1.elements == s.elements, content="true")
147
}
148

149
///|
150
/// Clear all elements in Stack
151
/// 
152
/// # Example
153
///
154
/// ```
155
///   let s = @stack.of([1, 2, 3])
156
///   s.clear()
157
///   assert_eq(s.length(), 0)
158
/// ```
159
pub fn[T] Stack::clear(self : Stack[T]) -> Unit {
160
  self.elements = @list.empty()
3✔
161
  self.len = 0
162
}
163

164
///|
165
test "clear" {
166
  let s = of([1, 2, 3])
167
  s.clear()
168
  inspect(s, content="Stack::[]")
169
}
170

171
///|
172
/// Same as the `clear()`, but returns an cleared stack
173
///
174
/// # Example
175
///
176
/// ```
177
///   let s = @stack.of([1, 2, 3]).return_with_clear()
178
///   assert_eq(s.length(), 0)
179
/// ```
180
pub fn[T] Stack::return_with_clear(self : Stack[T]) -> Stack[T] {
181
  self.clear()
1✔
182
  self
183
}
184

185
///|
186
test "return_with_clear" {
187
  let s = of([1, 2, 3]).return_with_clear()
188
  inspect(s, content="Stack::[]")
189
}
190

191
///|
192
/// Push an element into the stack.
193
/// 
194
/// # Example
195
///
196
/// ```
197
///   let s = @stack.new()
198
///   s.push(1)
199
///   assert_eq(s.length(), 1)
200
/// ```
201
pub fn[T] Stack::push(self : Stack[T], x : T) -> Unit {
202
  self.elements = @list.cons(x, self.elements)
13✔
203
  self.len = self.len + 1
204
}
205

206
///|
207
test "push" {
208
  let s = new()
209
  s.push(1)
210
  inspect(s, content="Stack::[1]")
211
  inspect(s.len, content="1")
212
}
213

214
///|
215
/// Push other stack into the current stack.
216
/// 
217
/// # Example
218
///
219
/// ```
220
///   let s = @stack.of([1, 2, 3])
221
///   let s1 : Stack[Int] = @stack.new()
222
///   s1.push_stack(s)
223
///   assert_eq(s1.length(), 3)
224
/// ```
225
pub fn[T] Stack::push_stack(self : Stack[T], stack : Stack[T]) -> Unit {
226
  stack.elements.iter().each(fn(i) { self.push(i) })
1✔
227
}
228

229
///|
230
test "push_stack" {
231
  let s = of([1, 2, 3])
232
  let s1 : Stack[Int] = new()
233
  s1.push_stack(s)
234
  inspect(s1, content="Stack::[3, 2, 1]")
235
  inspect(s.length() == s1.length(), content="true")
236
}
237

238
///|
239
/// Push an array into the stack.
240
/// 
241
/// # Example
242
///
243
/// ```
244
///   let s : Stack[Int] = @stack.new()
245
///   s.push_array([1, 2, 3])
246
///   assert_eq(s.length(), 3)
247
/// ```
248
pub fn[T] Stack::push_array(self : Stack[T], array : Array[T]) -> Unit {
249
  array.each(fn(i) { self.push(i) })
1✔
250
}
251

252
///|
253
test "push_array" {
254
  let s : Stack[Int] = new()
255
  s.push_array([1, 2, 3])
256
  inspect(s, content="Stack::[3, 2, 1]")
257
  inspect(s.len, content="3")
258
}
259

260
///|
261
/// Pop an element from the top of the stack.
262
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
263
///
264
/// # Example
265
///
266
/// ```
267
///   let s = @stack.of([1, 2, 3])
268
///   let s1 : Stack[Int] = @stack.new()
269
///   assert_eq(s.pop(), Some(1))
270
///   assert_eq(s.length(), 2)
271
///   assert_eq(s1.pop(), None)
272
/// ```
273
pub fn[T] Stack::pop(self : Stack[T]) -> T? {
274
  match self.elements {
3✔
275
    More(hd, tail=tl) => {
2✔
276
      self.elements = tl
277
      self.len = self.len - 1
278
      Some(hd)
279
    }
280
    Empty => None
1✔
281
  }
282
}
283

284
///|
285
test "pop" {
286
  let s = of([1, 2, 3])
287
  let s1 : Stack[Int] = new()
288
  debug_inspect(s.pop(), content="Some(1)")
289
  inspect(s, content="Stack::[2, 3]")
290
  inspect(s.len, content="2")
291
  debug_inspect(s1.pop(), content="None")
292
  inspect(s1, content="Stack::[]")
293
  inspect(s1.len, content="0")
294
}
295

296
///|
297
/// Pop an element from the top of the stack.
298
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
299
///
300
/// @alert unsafe "Panic if the stack is empty."
301
pub fn[T] Stack::unsafe_pop(self : Stack[T]) -> T {
302
  match self.elements {
3✔
303
    More(hd, tail=tl) => {
2✔
304
      self.elements = tl
305
      self.len = self.len - 1
306
      hd
307
    }
308
    Empty => abort("pop of empty stack")
1✔
309
  }
310
}
311

312
///|
313
test "unsafe_pop" {
314
  let s = of([1, 2, 3])
315
  inspect(s.unsafe_pop(), content="1")
316
  inspect(s, content="Stack::[2, 3]")
317
  inspect(s.len, content="2")
318
}
319

320
///|
321
/// Drop the element at the top of the stack.
322
/// Like pop, but does not return elements and does nothing if the Stack is empty.
323
///
324
/// # Example
325
///
326
/// ```
327
///   let s = @stack.of([1, 2, 3])
328
///   s.drop()
329
///   assert_eq(s.length(), 2)
330
/// ```
331
pub fn[T] Stack::drop(self : Stack[T]) -> Unit {
332
  match self.elements {
2✔
333
    More(_hd, tail=tl) => {
2✔
334
      self.elements = tl
335
      self.len = self.len - 1
336
    }
UNCOV
337
    Empty => ()
×
338
  }
339
}
340

341
///|
342
test "drop" {
343
  let s = of([1, 2, 3])
344
  s.drop()
345
  inspect(s, content="Stack::[2, 3]")
346
  inspect(s.len, content="2")
347
}
348

349
///|
350
/// Drop the element at the top of the stack.
351
/// Like drop, but when the drop is successful, it returns `Ok(())`, and when it fails, it returns `Err(())`
352
///
353
/// # Example
354
///
355
/// ```
356
///   let s = @stack.of([1, 2, 3])
357
///   let r = s.drop_result() // Ok(())
358
///   assert_eq(r, Ok(()))
359
/// ```
360
pub fn[T] Stack::drop_result(self : Stack[T]) -> Result[Unit, Unit] {
361
  match self.elements {
2✔
362
    More(_hd, tail=tl) => {
1✔
363
      self.elements = tl
364
      self.len = self.len - 1
365
      Ok(())
366
    }
367
    Empty => Err(())
1✔
368
  }
369
}
370

371
///|
372
test "drop_result" {
373
  let s = of([1, 2, 3])
374
  let s1 : Stack[Int] = new()
375
  inspect(s1.drop_result() == Err(()), content="true")
376
  inspect(s.drop_result() == Ok(()), content="true")
377
  inspect(s, content="Stack::[2, 3]")
378
  inspect(s.len, content="2")
379
}
380

381
///|
382
/// Only the top element of the stack is returned and will not be pop or drop.
383
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
384
///
385
/// # Example
386
///
387
/// ```
388
///   let s = Stack::from_array([1, 2, 3])
389
///   assert_eq(s.peek(), Some(1))
390
///   assert_eq(s.length(), 3)
391
/// ```
392
pub fn[T] Stack::peek(self : Stack[T]) -> T? {
393
  self.elements.head()
2✔
394
}
395

396
///|
397
test "peek" {
398
  let s = of([1, 2, 3])
399
  debug_inspect(s.peek(), content="Some(1)")
400
  inspect(s, content="Stack::[1, 2, 3]")
401
  inspect(s.len, content="3")
402
}
403

404
///|
405
/// Only the top element of the stack is returned and will not be pop or drop.
406
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
407
///
408
/// @alert unsafe "Panic if the stack is empty."
409
pub fn[T] Stack::unsafe_peek(self : Stack[T]) -> T {
410
  self.elements.unsafe_head()
4✔
411
}
412

413
///|
414
test "unsafe_peek" {
415
  let s : Stack[Int] = of([1, 2, 3])
416
  inspect(s.unsafe_peek(), content="1")
417
  inspect(s, content="Stack::[1, 2, 3]")
418
  inspect(s.len, content="3")
419
}
420

421
///|
422
/// If stack is empty, return true, otherwise return false.
423
///
424
/// # Example
425
///
426
/// ```
427
///   let s = @stack.of([1, 2, 3])
428
///   assert_false(s.is_empty())
429
///   let empty : Stack[Unit] = @stack.new()
430
///   assert_true(empty.is_empty())
431
/// ```
432
pub fn[T] Stack::is_empty(self : Stack[T]) -> Bool {
433
  self.len == 0
3✔
434
}
435

436
///|
437
test "is_empty" {
438
  let empty : Stack[Unit] = new()
439
  inspect(of([1, 2, 3]).is_empty(), content="false")
440
  inspect(empty.is_empty(), content="true")
441
}
442

443
///|
444
/// Returns the number of elements of the Stack
445
pub fn[T] Stack::length(self : Stack[T]) -> Int {
446
  self.len
3✔
447
}
448

449
///|
450
/// Iterates over the elements of the stack from top to bottom.
451
/// 
452
/// # Example
453
/// ```
454
///   let s = @stack.of([1, 2, 3])
455
///   let mut sum = 0
456
///   s.each(fn(i) { sum = sum + i })
457
///   assert_eq(sum, 6)
458
/// ```
459
pub fn[T] Stack::each(self : Stack[T], f : (T) -> Unit) -> Unit {
460
  self.elements.iter().each(f)
3✔
461
}
462

463
///|
464
test "iter" {
465
  let s : Stack[Int] = new()
466
  let mut sum = 0
467
  let mut sub = 0
468
  s.each(fn(i) { sum = sum + i })
469
  inspect(sum, content="0")
470
  s.push(1)
471
  s.push(2)
472
  s.push(3)
473
  inspect(s.unsafe_peek(), content="3")
474
  sum = 0
475
  sub = s.unsafe_peek()
476
  s.each(fn(i) { sum = sum + i })
477
  s.each(fn(i) { sub = sub - i }) // 3 - 3 - 2 - 1
478
  inspect(sum, content="6")
479
  inspect(sub, content="-3")
480
}
481

482
///|
483
/// Folds over the elements of the stack from top to bottom.
484
/// 
485
/// # Example
486
/// ```
487
///   let s = @stack.of([1, 2, 3])
488
///   let sum = s.fold(init=0, fn(acc, i) { acc + i })
489
///   assert_eq(sum, 6)
490
/// ```
491
pub fn[T, U] Stack::fold(self : Stack[T], init~ : U, f : (U, T) -> U) -> U {
492
  self.elements.fold(init~, f)
1✔
493
}
494

495
///|
496
test "fold" {
497
  let s = of([1, 2, 3])
498
  let sum = s.fold(init=0, fn(acc, i) { acc + i })
499
  inspect(sum, content="6")
500
}
501

502
///|
503
/// Covert stack to an iterator.
504
/// 
505
/// # Example
506
/// ```
507
/// let stack = @stack.new()
508
/// 
509
/// stack.push(3)
510
/// stack.push(2)
511
/// stack.push(1)
512
/// inspect(stack.iter(), content="[1, 2, 3]")
513
/// ```
514
pub fn[T] Stack::iter(self : Stack[T]) -> Iter[T] {
515
  self.elements.iter()
2✔
516
}
517

518
///|
519
/// Convert stack to array.
520
///
521
/// # Example
522
///
523
/// ```
524
///   assert_eq(@stack.of([1, 2, 3]).to_array(), [1, 2, 3])
525
/// ```
526
pub fn[T] Stack::to_array(self : Stack[T]) -> Array[T] {
527
  self.elements.to_array()
2✔
528
}
529

530
///|
531
test "to_array" {
532
  debug_inspect(of([3, 2, 1]).to_array(), content="[3, 2, 1]")
533
}
534

535
///|
536
/// Compare two stacks.
537
///
538
/// NOTE: Since the current standard library @immut/list.T lacks the equal or op_equal function, 
539
/// this function internally implements the equal function of @immut/list.T.
540
///
541
/// # Example
542
///
543
/// ```
544
///   assert_true(@stack.of([2, 4, 6]).equal(@stack.of([2, 4, 6])))
545
/// ```
546
pub fn[T : Eq] Stack::equal(self : Stack[T], other : Stack[T]) -> Bool {
547
  if self.len == other.len {
2✔
548
    self.elements == other.elements
2✔
549
  } else {
550
    false
×
551
  }
552
}
553

554
///|
555
pub fn[T : Eq] Stack::op_equal(self : Stack[T], other : Stack[T]) -> Bool {
UNCOV
556
  self.equal(other)
×
557
}
558

559
///|
560
test "equal" {
561
  inspect(of([2, 4, 6]).equal(of([2, 4, 6])), content="true")
562
  inspect(of([2, 4, 6]).equal(of([2, 4, 7])), content="false")
563
}
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

© 2026 Coveralls, Inc