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

moonbitlang / x / 668

27 Oct 2025 06:27AM UTC coverage: 90.323% (-0.004%) from 90.327%
668

push

github

peter-jerry-ye
fix: Remove anti-pattern of matching try

1 of 2 new or added lines in 1 file covered. (50.0%)

6 existing lines in 2 files now uncovered.

1988 of 2201 relevant lines covered (90.32%)

397.78 hits per line

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

92.68
/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(s.is_empty())
25
/// ```
26
#as_free_fn
27
pub fn[T] Stack::new() -> Stack[T] {
28
  { elements: @list.from_array([]), len: 0 }
22✔
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() }
5✔
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.of(array), len: array.length() }
40✔
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 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
test "to_string" {
107
  let empty : Stack[Int] = new()
108
  inspect(empty, content="Stack::[]")
109
  inspect(of([1, 2, 3, 4, 5]), content="Stack::[1, 2, 3, 4, 5]")
110
}
111

112
///|
113
/// Create a stack based on another stack.
114
///
115
/// # Example
116
///
117
/// ```
118
///   let s = @stack.of([1, 2, 3])
119
///   let s1 = Stack::from_stack(s)
120
///   assert_eq(s1.length(), 3)
121
/// ```
122
pub fn[T] Stack::from_stack(other : Stack[T]) -> Stack[T] {
123
  { ..other }
2✔
124
}
125

126
///|
127
test "from_stack" {
128
  let s = of([1, 2, 3])
129
  let s1 = Stack::from_stack(s)
130
  inspect(s1.elements == s.elements, content="true")
131
}
132

133
///|
134
/// Clear all elements in Stack
135
/// 
136
/// # Example
137
///
138
/// ```
139
///   let s = @stack.of([1, 2, 3])
140
///   s.clear()
141
///   assert_eq(s.length(), 0)
142
/// ```
143
pub fn[T] clear(self : Stack[T]) -> Unit {
144
  self.elements = @list.empty()
5✔
145
  self.len = 0
146
}
147

148
///|
149
test "clear" {
150
  let s = of([1, 2, 3])
151
  s.clear()
152
  inspect(s, content="Stack::[]")
153
}
154

155
///|
156
/// Same as the `clear()`, but returns an cleared stack
157
///
158
/// # Example
159
///
160
/// ```
161
///   let s = @stack.of([1, 2, 3]).return_with_clear()
162
///   assert_eq(s.length(), 0)
163
/// ```
164
pub fn[T] return_with_clear(self : Stack[T]) -> Stack[T] {
165
  self.clear()
2✔
166
  self
167
}
168

169
///|
170
test "return_with_clear" {
171
  let s = of([1, 2, 3]).return_with_clear()
172
  inspect(s, content="Stack::[]")
173
}
174

175
///|
176
/// Push an element into the stack.
177
/// 
178
/// # Example
179
///
180
/// ```
181
///   let s = @stack.new()
182
///   s.push(1)
183
///   assert_eq(s.length(), 1)
184
/// ```
185
pub fn[T] push(self : Stack[T], x : T) -> Unit {
186
  self.elements = @list.cons(x, self.elements)
26✔
187
  self.len = self.len + 1
188
}
189

190
///|
191
test "push" {
192
  let s = new()
193
  s.push(1)
194
  inspect(s, content="Stack::[1]")
195
  inspect(s.len, content="1")
196
}
197

198
///|
199
/// Push other stack into the current stack.
200
/// 
201
/// # Example
202
///
203
/// ```
204
///   let s = @stack.of([1, 2, 3])
205
///   let s1 : Stack[Int] = @stack.new()
206
///   s1.push_stack(s)
207
///   assert_eq(s1.length(), 3)
208
/// ```
209
pub fn[T] push_stack(self : Stack[T], stack : Stack[T]) -> Unit {
210
  stack.elements.iter().each(fn(i) { self.push(i) })
2✔
211
}
212

213
///|
214
test "push_stack" {
215
  let s = of([1, 2, 3])
216
  let s1 : Stack[Int] = new()
217
  s1.push_stack(s)
218
  inspect(s1, content="Stack::[3, 2, 1]")
219
  inspect(s.length() == s1.length(), content="true")
220
}
221

222
///|
223
/// Push an array into the stack.
224
/// 
225
/// # Example
226
///
227
/// ```
228
///   let s : Stack[Int] = @stack.new()
229
///   s.push_array([1, 2, 3])
230
///   assert_eq(s.length(), 3)
231
/// ```
232
pub fn[T] push_array(self : Stack[T], array : Array[T]) -> Unit {
233
  array.each(fn(i) { self.push(i) })
2✔
234
}
235

236
///|
237
test "push_array" {
238
  let s : Stack[Int] = new()
239
  s.push_array([1, 2, 3])
240
  inspect(s, content="Stack::[3, 2, 1]")
241
  inspect(s.len, content="3")
242
}
243

244
///|
245
/// Pop an element from the top of the stack.
246
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
247
///
248
/// # Example
249
///
250
/// ```
251
///   let s = @stack.of([1, 2, 3])
252
///   let s1 : Stack[Int] = @stack.new()
253
///   assert_eq(s.pop(), Some(1))
254
///   assert_eq(s.length(), 2)
255
///   assert_eq(s1.pop(), None)
256
/// ```
257
pub fn[T] pop(self : Stack[T]) -> T? {
258
  match self.elements {
5✔
259
    More(hd, tail=tl) => {
3✔
260
      self.elements = tl
261
      self.len = self.len - 1
262
      Some(hd)
263
    }
264
    Empty => None
2✔
265
  }
266
}
267

268
///|
269
test "pop" {
270
  let s = of([1, 2, 3])
271
  let s1 : Stack[Int] = new()
272
  inspect(s.pop(), content="Some(1)")
273
  inspect(s, content="Stack::[2, 3]")
274
  inspect(s.len, content="2")
275
  inspect(s1.pop(), content="None")
276
  inspect(s1, content="Stack::[]")
277
  inspect(s1.len, content="0")
278
}
279

280
///|
281
/// Pop an element from the top of the stack.
282
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
283
///
284
/// @alert unsafe "Panic if the stack is empty."
285
pub fn[T] unsafe_pop(self : Stack[T]) -> T {
286
  match self.elements {
3✔
287
    More(hd, tail=tl) => {
2✔
288
      self.elements = tl
289
      self.len = self.len - 1
290
      hd
291
    }
292
    Empty => abort("pop of empty stack")
1✔
293
  }
294
}
295

296
///|
297
test "unsafe_pop" {
298
  let s = of([1, 2, 3])
299
  inspect(s.unsafe_pop(), content="1")
300
  inspect(s, content="Stack::[2, 3]")
301
  inspect(s.len, content="2")
302
}
303

304
///|
305
/// Drop the element at the top of the stack.
306
/// Like pop, but does not return elements and does nothing if the Stack is empty.
307
///
308
/// # Example
309
///
310
/// ```
311
///   let s = @stack.of([1, 2, 3])
312
///   s.drop()
313
///   assert_eq(s.length(), 2)
314
/// ```
315
pub fn[T] drop(self : Stack[T]) -> Unit {
316
  match self.elements {
3✔
317
    More(_hd, tail=tl) => {
3✔
318
      self.elements = tl
319
      self.len = self.len - 1
320
    }
UNCOV
321
    Empty => ()
×
322
  }
323
}
324

325
///|
326
test "drop" {
327
  let s = of([1, 2, 3])
328
  s.drop()
329
  inspect(s, content="Stack::[2, 3]")
330
  inspect(s.len, content="2")
331
}
332

333
///|
334
/// Drop the element at the top of the stack.
335
/// Like drop, but when the drop is successful, it returns `Ok(())`, and when it fails, it returns `Err(())`
336
///
337
/// # Example
338
///
339
/// ```
340
///   let s = @stack.of([1, 2, 3])
341
///   let r = s.drop_result() // Ok(())
342
///   assert_eq(r, Ok(()))
343
/// ```
344
pub fn[T] drop_result(self : Stack[T]) -> Result[Unit, Unit] {
345
  match self.elements {
3✔
346
    More(_hd, tail=tl) => {
2✔
347
      self.elements = tl
348
      self.len = self.len - 1
349
      Ok(())
350
    }
351
    Empty => Err(())
1✔
352
  }
353
}
354

355
///|
356
test "drop_result" {
357
  let s = of([1, 2, 3])
358
  let s1 : Stack[Int] = new()
359
  inspect(s1.drop_result() == Err(()), content="true")
360
  inspect(s.drop_result() == Ok(()), content="true")
361
  inspect(s, content="Stack::[2, 3]")
362
  inspect(s.len, content="2")
363
}
364

365
///|
366
/// Only the top element of the stack is returned and will not be pop or drop.
367
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
368
///
369
/// # Example
370
///
371
/// ```
372
///   let s = Stack::from_array([1, 2, 3])
373
///   assert_eq(s.peek(), Some(1))
374
///   assert_eq(s.length(), 3)
375
/// ```
376
pub fn[T] peek(self : Stack[T]) -> T? {
377
  self.elements.head()
3✔
378
}
379

380
///|
381
test "peek" {
382
  let s = of([1, 2, 3])
383
  inspect(s.peek(), content="Some(1)")
384
  inspect(s, content="Stack::[1, 2, 3]")
385
  inspect(s.len, content="3")
386
}
387

388
///|
389
/// Only the top element of the stack is returned and will not be pop or drop.
390
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
391
///
392
/// @alert unsafe "Panic if the stack is empty."
393
pub fn[T] unsafe_peek(self : Stack[T]) -> T {
394
  self.elements.unsafe_head()
4✔
395
}
396

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

405
///|
406
/// If stack is empty, return true, otherwise return false.
407
///
408
/// # Example
409
///
410
/// ```
411
///   let s = @stack.of([1, 2, 3])
412
///   assert_false(s.is_empty())
413
///   let empty : Stack[Unit] = @stack.new()
414
///   assert_true(empty.is_empty())
415
/// ```
416
pub fn[T] is_empty(self : Stack[T]) -> Bool {
417
  self.len == 0
7✔
418
}
419

420
///|
421
test "is_empty" {
422
  let empty : Stack[Unit] = new()
423
  inspect(of([1, 2, 3]).is_empty(), content="false")
424
  inspect(empty.is_empty(), content="true")
425
}
426

427
///|
428
/// Returns the number of elements of the Stack
429
pub fn[T] length(self : Stack[T]) -> Int {
430
  self.len
15✔
431
}
432

433
///|
434
/// Iterates over the elements of the stack from top to bottom.
435
/// 
436
/// # Example
437
/// ```
438
///   let s = @stack.of([1, 2, 3])
439
///   let mut sum = 0
440
///   s.each(fn(i) { sum = sum + i })
441
///   assert_eq(sum, 6)
442
/// ```
443
pub fn[T] each(self : Stack[T], f : (T) -> Unit) -> Unit {
444
  self.elements.iter().each(f)
4✔
445
}
446

447
///|
448
test "iter" {
449
  let s : Stack[Int] = new()
450
  let mut sum = 0
451
  let mut sub = 0
452
  s.each(fn(i) { sum = sum + i })
453
  inspect(sum, content="0")
454
  s.push(1)
455
  s.push(2)
456
  s.push(3)
457
  inspect(s.unsafe_peek(), content="3")
458
  sum = 0
459
  sub = s.unsafe_peek()
460
  s.each(fn(i) { sum = sum + i })
461
  s.each(fn(i) { sub = sub - i }) // 3 - 3 - 2 - 1
462
  inspect(sum, content="6")
463
  inspect(sub, content="-3")
464
}
465

466
///|
467
/// Folds over the elements of the stack from top to bottom.
468
/// 
469
/// # Example
470
/// ```
471
///   let s = @stack.of([1, 2, 3])
472
///   let sum = s.fold(init=0, fn(acc, i) { acc + i })
473
///   assert_eq(sum, 6)
474
/// ```
475
pub fn[T, U] fold(self : Stack[T], init~ : U, f : (U, T) -> U) -> U {
476
  self.elements.fold(init~, f)
2✔
477
}
478

479
///|
480
test "fold" {
481
  let s = of([1, 2, 3])
482
  let sum = s.fold(init=0, fn(acc, i) { acc + i })
483
  inspect(sum, content="6")
484
}
485

486
///|
487
/// Covert stack to an iterator.
488
/// 
489
/// # Example
490
/// ```
491
/// let stack = @stack.new()
492
/// 
493
/// stack.push(3)
494
/// stack.push(2)
495
/// stack.push(1)
496
/// inspect(stack.iter(), content="[1, 2, 3]")
497
/// ```
498
pub fn[T] iter(self : Stack[T]) -> Iter[T] {
499
  self.elements.iter()
4✔
500
}
501

502
///|
503
/// Convert stack to array.
504
///
505
/// # Example
506
///
507
/// ```
508
///   assert_eq(@stack.of([1, 2, 3]).to_array(), [1, 2, 3])
509
/// ```
510
pub fn[T] to_array(self : Stack[T]) -> Array[T] {
511
  self.elements.to_array()
3✔
512
}
513

514
///|
515
test "to_array" {
516
  inspect(of([3, 2, 1]).to_array(), content="[3, 2, 1]")
517
}
518

519
///|
520
/// Compare two stacks.
521
///
522
/// NOTE: Since the current standard library @immut/list.T lacks the equal or op_equal function, 
523
/// this function internally implements the equal function of @immut/list.T.
524
///
525
/// # Example
526
///
527
/// ```
528
///   assert_true(@stack.of([2, 4, 6]).equal(@stack.of([2, 4, 6])))
529
/// ```
530
pub fn[T : Eq] equal(self : Stack[T], other : Stack[T]) -> Bool {
531
  if self.len == other.len {
3✔
532
    self.elements == other.elements
3✔
533
  } else {
UNCOV
534
    false
×
535
  }
536
}
537

538
///|
539
pub fn[T : Eq] op_equal(self : Stack[T], other : Stack[T]) -> Bool {
UNCOV
540
  self.equal(other)
×
541
}
542

543
///|
544
test "equal" {
545
  inspect(of([2, 4, 6]).equal(of([2, 4, 6])), content="true")
546
  inspect(of([2, 4, 6]).equal(of([2, 4, 7])), content="false")
547
}
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