User-agent parser library ported from uap-core rules with uap-python-compatible semantics
moon new hello_ua
cd hello_ua
moon add vicoproplus/moon_ua_parserPublishing status: as of 2026-09-13 the mooncakes registry has no published version of vicoproplus/moon_ua_parser yet (the registry API returns 404 for the module), so the moon add step above fails until the formal moon publish runs — a user-gated action, currently pending. The packaging itself is already dry-run-verified: the server accepted the package with status 202 and a 29-file zip (see ../docs/evidence/publish-dryrun-2026-09-13.log and the Publishing note in ../CHANGELOG.md). Once the registry lists version 0.2.0, this quickstart works as written.
pkgtype(kind: "executable")
import {
"vicoproplus/moon_ua_parser/src/ua_parser",
}///|
fn opt(v : String?) -> String {
match v {
Some(s) => s
None => "-"
}
}
///|
fn main {
let ua =
"Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13E238 Safari/601.1"
match @ua_parser.parse(ua) {
Ok(info) => {
let b = info.browser
let o = info.os
let d = info.device
println("browser : \{b.family} \{opt(b.major)}.\{opt(b.minor)}")
println("os : \{o.family} \{opt(o.major)}.\{opt(o.minor)}.\{opt(o.patch)}")
println("device : \{d.family} / \{opt(d.brand)} / \{opt(d.model)}")
}
Err(e) => println("parse error: \{e}")
}
}moon run --target native cmd/mainbrowser : Mobile Safari 9.0
os : iOS 9.3.1
device : iPhone / Apple / iPhonepub fn parse(ua : String, with_rule_index? : Bool = false) -> Result[UaInfo, UaError]
pub fn parse_browser(ua : String) -> Browser
pub fn parse_os(ua : String) -> OS
pub fn parse_device(ua : String) -> Devicemoon run --target native examples/middlewaremoon add vicoproplus/moon_ua_parser_crescentFramework adaptation (header mounting): crescent's Event has no
custom key-value store, so the adapter uses the framework-sanctioned
res.headers bypass — the full UaInfo JSON round-trips in an
X-Ua-Info response header, written before next() so downstream
handlers and the client both observe it; degraded parses emit one
forensics record through an injectable sink (crescent ships no logger
middleware).moon add vicoproplus/moon_ua_parser_marsFramework adaptation (Variables mounting): mars's Context carries a
typed key-value store (ctx.vars : Variables), so the adapter mounts the
browser / os / device families as native string variables, read back
handler-side via mounted_ua_info(ctx); forensics reuse mars's own
console log channel by default.| domain | cases | passed | rate | gate | status |
|---|---|---|---|---|---|
| browser | 1601 | 1601 | 100.00% | ≥99% | MET |
| os | 483 | 483 | 100.00% | ≥97% | MET |
| device | 16129 | 16129 | 100.00% | ≥97% | MET |
| backend | ops_per_sec | ns_per_parse |
|---|---|---|
| native | 23.64 | 42299995.40 |
| js | 66.56 | 15023080.99 |
| wasm | 23.95 | 41739215.19 |
bench-result backend=native ops_per_sec=23.64 ns_per_parse=42299995.40 sample_set_hash=sha256:3640d3b74cd4efd6e5e1723d8e23493e3399b8b616d977cd5e18fb66302c4244 samples_checksum=15142 rounds_consistent=true
bench-result backend=js ops_per_sec=66.56 ns_per_parse=15023080.99 sample_set_hash=sha256:3640d3b74cd4efd6e5e1723d8e23493e3399b8b616d977cd5e18fb66302c4244 samples_checksum=15142 rounds_consistent=true
bench-result backend=wasm ops_per_sec=23.95 ns_per_parse=41739215.19 sample_set_hash=sha256:3640d3b74cd4efd6e5e1723d8e23493e3399b8b616d977cd5e18fb66302c4244 samples_checksum=15142 rounds_consistent=truecd moon_ua_parser_lib
moon run --target native --release tests/bench
moon run --target js --release tests/bench
moon run --target wasm --release tests/benchInstall
Download zipUser-agent parser library ported from uap-core rules with uap-python-compatible semantics