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

moonbitlang / x / 702

12 Nov 2025 08:27AM UTC coverage: 87.36% (-3.0%) from 90.318%
702

Pull #208

github

web-flow
Merge b47937ff8 into 6fba90ceb
Pull Request #208: feat(path): add path MoonBit package

190 of 292 new or added lines in 5 files covered. (65.07%)

2177 of 2492 relevant lines covered (87.36%)

359.57 hits per line

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

0.0
/path/path.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
/// Terminology:
17
/// 
18
/// path component is original from [posix 4.13 pathname resolution](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13)
19

20
///|
NEW
21
let is_windows : Bool = @ffi.is_windows()
×
22

23
///|
24
/// Returns the last path component of the given path.
25
///
26
/// property: `@path.join(@path.dirname(path), @path.basename(path)) == path`
27
/// 
28
/// Warning: basename function not respect this POSIX standard, but consistent with Python `os.path` module.
29
/// 
30
pub fn basename(path : StringView) -> StringView {
NEW
31
  if is_windows {
×
NEW
32
    @win32.basename(path)
×
33
  } else {
NEW
34
    @posix.basename(path)
×
35
  }
36
}
37

38
///|
39
/// Returns path without its last path component and trailing slashes.
40
/// 
41
/// property: `@path.join(@path.dirname(path), @path.basename(path)) == path`
42
/// 
43
/// Warning: basename function not respect this POSIX standard, but consistent with Python `os.path` module.
44
/// 
45
pub fn dirname(path : StringView) -> StringView {
NEW
46
  if is_windows {
×
NEW
47
    @win32.dirname(path)
×
48
  } else {
NEW
49
    @posix.dirname(path)
×
50
  }
51
}
52

53
///|
54
/// Returns the string of the basename after the last `.` delimiter.
55
pub fn extname(path : StringView) -> StringView {
NEW
56
  if is_windows {
×
NEW
57
    @win32.extname(path)
×
58
  } else {
NEW
59
    @posix.extname(path)
×
60
  }
61
}
62

63
///|
64
/// Returns whether the given path is absolute.
65
/// 
66
/// edge cases: when path is empty, return false
67
pub fn is_absolute(path : StringView) -> Bool {
NEW
68
  if is_windows {
×
NEW
69
    @win32.is_absolute(path)
×
70
  } else {
NEW
71
    @posix.is_absolute(path)
×
72
  }
73
}
74

75
///|
76
/// 1. string concatenation with OS platform specific path separator
77
/// 2. if rhs is absolute path, return rhs.
78
/// 
79
/// edge cases:
80
///  1. when lhs and rhs both are empty, return empty string
81
///  2. ignore empty string
82
pub fn join(lhs : StringView, rhs : StringView) -> StringView {
NEW
83
  if is_windows {
×
NEW
84
    @win32.join(lhs, rhs)
×
85
  } else {
NEW
86
    @posix.join(lhs, rhs)
×
87
  }
88
}
89

90
///|
91
/// 1. resolve `.` by directly removing it
92
/// 2. resolve `..` by removing the preceding path component if exists, otherwise keep it.
93
/// 3. remove redundant slashes or backslashes
94
/// 4. preserve trailing slash or backslash
95
/// 
96
/// edge cases:
97
///   1. when path is empty, return empty string
98
///   2. when path is contains two leading forward slashes like `//`, return `//`. respect POSIX standard, this behavior is inconsistent with Node.js path module.
99
/// 
100
pub fn normalize(path : StringView) -> StringView {
NEW
101
  if is_windows {
×
NEW
102
    @win32.normalize(path)
×
103
  } else {
NEW
104
    @posix.normalize(path)
×
105
  }
106
}
107

108
///|
109
/// Return the `to` relative path when `from` is the current working directory.
110
/// 
111
/// property: `@path.join(from,@path.relative(from,to)) == @path.normalize(to)`
112
/// 
113
/// edge cases: 
114
///  1. when `@path.normalize(from) == @path.normalize(to)`, return empty string
115
///  2. when `from` and `to` have different prefixes, return empty string
116
/// 
117
/// Warning: cwd is already resolve symbolic link and normalized, but path doesn't.
118
pub fn relative(from : StringView, to : StringView) -> StringView {
NEW
119
  if is_windows {
×
NEW
120
    @win32.relative(from, to)
×
121
  } else {
NEW
122
    @posix.relative(from, to)
×
123
  }
124
}
125

126
///|
127
/// 1. if path is already absolute, return path normalized.
128
/// 2. if path is relative, join current working directory and path, and then normalize it.
129
///
130
/// Warning: cwd is already resolve symbolic link and normalized, but path doesn't.
131
pub fn resolve(path : StringView) -> StringView {
NEW
132
  if is_windows {
×
NEW
133
    @win32.resolve(path)
×
134
  } else {
NEW
135
    @posix.resolve(path)
×
136
  }
137
}
138

139
///|
140
/// OS platform specific path delimiter for environment variables. e.g., PATH
NEW
141
pub let delimiter : Char = if is_windows { ';' } else { ':' }
×
142

143
///|
144
/// OS platform specific path component separator.
NEW
145
pub let sep : Char = if is_windows { '\\' } else { '/' }
×
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