RFC 8288 Web Linking and RFC 9264 Linkset parser, serializer, query and audit toolkit for MoonBit.
moon.mod module manifest (15614376790/moon-weblink 0.1.0)
lib source (.mbt) parser, serializer, model, linkset, audit, query, ...
cmd/weblink-tool/ command-line tool
examples/ five runnable example programs
testdata/iana/ offline IANA registry snapshot (CSV + SOURCE.json)
scripts/ verification and generation helpers
docs/ design and process documentationmoon check --target native
moon test --target native
moon run cmd/weblink-tool -- parse --input '<https://example.com/page/2>; rel="next"'
moon run examples/paginationpowershell -ExecutionPolicy Bypass -File scripts\verify_all.ps1fn main {
// Parse a Link header field value into a shared model.
let links = @weblink.parse_link_header(
"</users?page=2>; rel=\"next\", </users?page=1>; rel=\"prev\"",
@weblink.Limits::default(),
)
match links {
Err(e) => println("error: \{e.to_display()}")
Ok(links) => {
// Query helpers: find next/prev, filter by relation or media type.
match @weblink.find_next(links) {
Some(next) => println("next: \{next.target()}")
None => println("no next link")
}
// Convert the whole collection to application/linkset+json and back.
let json = @weblink.serialize_linkset_json(
@weblink.LinkSet::from_links(links),
)
println(json)
}
}
}weblink-tool parse parse a Link header and print each link
weblink-tool validate report valid / invalid
weblink-tool canonicalize emit the canonical Link header form
weblink-tool query find links by --rel / --type / --hreflang
weblink-tool to-linkset-json convert a Link header to application/linkset+json
weblink-tool from-linkset-json convert application/linkset+json to a Link header
weblink-tool to-linkset-text convert to application/linkset text
weblink-tool relation query the offline IANA relation registry
weblink-tool audit audit a Link header for issues
weblink-tool stats library and registry statistics
weblink-tool version | help| Example | What it shows |
|---|---|
| examples/parse_header | parse a Link header and print each link |
| examples/pagination | walk next / prev pagination links; resolve a relative URI against a base |
| examples/linkset_json | convert Link header → linkset JSON → header |
| examples/relation_query | query the offline IANA registry; filter links by relation |
| examples/audit_header | run the deterministic audit and print every finding |
pub struct ExtendedValue {
charset : String
language : String?
value : String
}pub struct Limits {
max_input_bytes : Int
max_links : Int
max_params_per_link : Int
max_relations_per_link : Int
max_target_bytes : Int
max_parameter_name_bytes : Int
max_parameter_value_bytes : Int
max_quoted_string_bytes : Int
max_linkset_links : Int
max_json_bytes : Int
}pub(all) enum LinkErrorKind {
EmptyInput
UnexpectedCharacter
ExpectedAngleBracket
UnterminatedTarget
InvalidTarget
InvalidToken
MissingParameterName
InvalidParameter
UnterminatedQuotedString
InvalidQuotedPair
InvalidRelation
InvalidExtensionRelation
InvalidPercentEncoding
UnsupportedCharset
InvalidUtf8
InvalidLanguageTag
InvalidJson
InvalidJsonShape
InvalidLinkset
DuplicateParameter
LimitExceeded
TrailingInput
InvalidContextValue
InvalidMediaType
} derive(Eq)pub(all) enum LinkErrorStage {
Input
Header
LinkValue
Target
Parameter
Relation
QuotedString
ExtendedValue
UriReference
LinksetText
LinksetJson
Registry
Limit
} derive(Eq)pub struct LinkParameter {
name : String
value : String?
quoted : Bool
}pub struct RelationInfo {
name : String
description : String
reference : String
notes : String
}pub enum RelationType {
Registered(String)
Extension(String)
}pub struct Scanner {
bytes : Bytes
len : Int
pos : Int
allow_newline : Bool
}pub struct UriReference {
scheme : String?
authority : String?
path : String
query : String?
fragment : String?
}pub struct WebLink {
target : String
relations : Array[RelationType]
anchor : String?
hreflang : Array[String]
media : String?
title : String?
title_star : ExtendedValue?
media_type : String?
extensions : Array[LinkParameter]
}fn can_be_token(value : String) -> Boolfn is_bad_control(b : Byte) -> Boolfn is_ext_value_name(name : String) -> Boolfn is_obs_text(b : Byte) -> Boolfn is_registered_relation(name : String) -> Boolfn library_version() -> Stringfn link_error_at(stage : LinkErrorStage, kind : LinkErrorKind, offset : Int, context : String) -> LinkErrorfn max_context_bytes() -> Intfn media_type_token_char(b : Byte) -> Boolfn parse_link_header_detailed(input : String, limits : Limits) -> Result[LinkHeaderParse, LinkError]fn ptokenchar(b : Byte) -> Boolfn qdtext_char(b : Byte) -> Boolfn quoted_pair_ok(b : Byte) -> Boolfn registered_relation_count() -> Intfn remove_dot_segments(path : String) -> Stringfn serialize_quoted_string(value : String) -> Stringfn uri_gen_delim(b : Byte) -> Boolfn uri_pchar(b : Byte) -> Boolfn uri_sub_delim(b : Byte) -> Boolfn uri_unreserved(b : Byte) -> Boolfn valid_language_tag(tag : String) -> BoolRFC 8288 Web Linking and RFC 9264 Linkset parser, serializer, query and audit toolkit for MoonBit.