A bidirectional map (bijection) with reverse lookup, insertion order, and index access - MoonBit port of Rust's bimap
let m = @aurasuisui/bimap.new()
m.insert("alice", "admin") |> ignore
m.insert("bob", "user") |> ignore
// Forward and reverse lookup:
println(m.get_by_left("alice")) // Some("admin")
println(m.get_by_right("user")) // Some("bob")
// Index access (insertion order preserved):
println(m.get_index(0)) // Some(("alice", "admin"))| Feature | built-in Map | BiMap | indexmap |
|---|---|---|---|
| key → value | ✅ | ✅ | ✅ |
| value → key (reverse) | ❌ | ✅ | ❌ |
| index access get_index(i) | ❌ | ✅ | ✅ |
| keys unique | ✅ | ✅ | ✅ |
| values also unique (bijection) | ❌ | ✅ | ❌ |
| preserves insertion order | impl-defined | ✅ | ✅ |
| Eq/Hash semantics | order-independent | order-independent | order-sensitive |
import {
"aurasuisui/bimap@0.1.1",
}import {
"aurasuisui/bimap",
}| Case | Condition | insert returns | len change |
|---|---|---|---|
| C0 | neither l nor r present | Neither | +1 |
| C1 | the exact pair (l, r) already present | Pair(l, r) | 0 |
| C2 | l was bound to r'≠r; r free | Left(l, r') | 0 |
| C3 | r was bound to l'≠l; l free | Right(l', r) | 0 |
| C4 | l→r' and l'→r both exist | Both((l,r'), (l',r)) | −1 |
C4 collapses two pairs into one — insert can reduce the map's size! This mirrors Rust bimap's Overwritten::Both exactly.
let m = @aurasuisui/bimap.new()
m.insert("a", 1) |> ignore // Neither {a↔1}
m.insert("b", 2) |> ignore // Neither {a↔1, b↔2}
m.insert("a", 4) |> ignore // Left(a, 1) {a↔4, b↔2}
m.insert("c", 2) |> ignore // Right(b, 2) {a↔4, c↔2}
let r = m.insert("a", 2) // Both((a,4),(c,2)) {a↔2} — len 2→1!| Category | Methods |
|---|---|
| Construct | new(), with_capacity(n), from_array(pairs), default(), copy() |
| Query | len(), is_empty(), capacity() |
| Insert | insert(l, r) -> Overwritten, insert_no_overwrite(l, r) -> Result[Unit,(L,R)] |
| Forward | get_by_left(l), contains_left(l), remove_by_left(l) -> R? |
| Reverse | get_by_right(r), contains_right(r), remove_by_right(r) -> L? |
| Index | get_index(i), get_index_of_left(l), get_index_of_right(r), first(), last() |
| Iterate | iter(), lefts(), rights(), into_array() |
| Convert | to_inverse() -> BiMap[R, L] |
| Traits | Debug, Default, Show, Hash, Eq, ToJson, Arbitrary |
Note: the cmd/* example packages are standalone modules excluded from the root workspace (they import the published aurasuisui/bimap). To run one, make the package resolvable (e.g. after moon publish) and run moon run cmd/<name>.
moon check # type check
moon test # run all 229 tests
moon fmt # format
moon build # buildtype BiMap[L, R]A bidirectional map (bijection) with reverse lookup, insertion order, and index access - MoonBit port of Rust's bimap