Expand description
Apple Associated Domains semantics for Rust and WebAssembly.
blazingly-aasa parses, validates, matches, explains, and compares apple-app-site-association
files. It is a semantic engine, not a fetcher: it never touches the network, never opens an
.ipa, and never claims to know what a device will do. Give it bytes and explicit context, and
it tells you exactly what the document says.
§Three separate questions
- Is this parseable?
AasaDocument::parsefails only on invalid JSON, a non-object root, or an oversized payload. - Is this sane?
CompiledAasa::validatereturns aValidationReportof stable, machine-readableDiagnosticCodes rather than a single yes/no. - Does this URL match?
CompiledAasa::match_urlreturnsMatchDecision::Match,MatchDecision::Exclude, orMatchDecision::NoMatch— with a trace explaining why.
A URL that does not match is not an error, and neither is one that is excluded. Both are answers.
§Matching a URL
use blazingly_aasa::{CompiledAasa, MatchDecision};
let bytes = br#"{
"applinks": {
"details": [{
"appIDs": ["ABCDE12345.com.example.app"],
"components": [
{ "/": "/help/website/*", "exclude": true },
{ "/": "/help/*", "?": { "articleNumber": "????" } }
]
}]
}
}"#;
let aasa = CompiledAasa::parse(bytes)?;
let app = "ABCDE12345.com.example.app";
let hit = aasa.match_url("example.com", app, "https://example.com/help/1?articleNumber=4815")?;
assert_eq!(hit.decision, MatchDecision::Match);
let blocked = aasa.match_url("example.com", app, "https://example.com/help/website/faq")?;
assert_eq!(blocked.decision, MatchDecision::Exclude);
// Three characters, not four: the query predicate rejects it.
let miss = aasa.match_url("example.com", app, "https://example.com/help/1?articleNumber=481")?;
assert_eq!(miss.decision, MatchDecision::NoMatch);§Explaining a decision
Every result formats itself into something you can paste into a bug report:
let result = aasa.match_url("example.com", "A.b", "https://example.com/sell/42")?;
println!("{result}");§Comparing two files
CompiledAasa::semantic_diff compares behaviour rather than text, so moving
caseSensitive from every component up into defaults reports no change, while reordering two
rules does:
use blazingly_aasa::CompiledAasa;
let spelled_out = CompiledAasa::parse(br#"{"applinks":{"details":[{
"appIDs": ["A.b"],
"components": [{ "/": "/buy/*", "caseSensitive": false }]
}]}}"#)?;
let refactored = CompiledAasa::parse(br#"{"applinks":{"details":[{
"appIDs": ["A.b"],
"defaults": { "caseSensitive": false },
"components": [{ "/": "/buy/*" }]
}]}}"#)?;
assert!(spelled_out.semantic_diff(&refactored).is_equivalent());
assert!(!spelled_out.structural_equal(&refactored));§What this crate will not do
It does not fetch .well-known/apple-app-site-association, talk to Apple’s CDN, read
entitlements out of a signed binary, or model device state. Those belong in the tools that use
this crate. See docs/parity.md for the behaviours that are verified against Apple’s
documentation and the ones that are still open questions.
Structs§
- Aasa
Diff - The result of comparing two documents.
- Aasa
Document - A parsed
apple-app-site-associationdocument. - AppLink
Detail - One entry of
applinks.details. - AppLinks
- The
applinkssection. - AppService
- A service that is configured with a flat list of app identifiers.
- Compiled
Aasa - A document normalised for matching, explaining, and comparing.
- Component
Rule - One entry of a
componentsarray. - Component
Trace - One component comparison inside a rule.
- Detail
Trace - One
applinks.detailsentry considered during matching. - Diagnostic
- A single validation finding, anchored at a location inside the document.
- Effective
Defaults - The effective pattern-matching settings for one rule, after resolving the defaults hierarchy.
- Effective
Rule - A rule reduced to exactly what decides matching.
- Match
Defaults - Pattern-matching defaults, which may appear at the domain and app level.
- Match
Result - The result of matching one URL for one application identifier.
- Match
Trace - The full record of a match attempt.
- Parse
Error - A failure to parse an
apple-app-site-associationpayload. - Parse
Options - Limits applied while parsing.
- Pattern
Syntax Error - A pattern that could not be compiled.
- Rule
Trace - One rule evaluation.
- UrlError
- A URL that could not be split into the components required for matching.
- UrlParts
- The pieces of a URL that Associated Domains matching cares about.
- Validation
Report - The result of validating a document.
- Wildcard
Pattern - A compiled Apple URL-component pattern.
Enums§
- Component
Reason - Why one component matched or failed.
- Diagnostic
Code - A stable, machine-readable identifier for a validation finding.
- Effective
Query - A
?constraint reduced to its comparable form. - Error
- The crate-wide error type.
- Match
Decision - The outcome of matching a URL against a document.
- Parse
Error Kind - Why an
apple-app-site-associationpayload could not be turned into a document. - Query
Predicate - One entry of a
?dictionary. - Query
Rule - The
?key, which Apple allows to be either a pattern or a dictionary of predicates. - Semantic
Change - One semantic difference between two documents.
- Service
- An Associated Domains service.
- Severity
- How seriously to take a diagnostic.
- Stop
Reason - Why matching stopped where it did.
- UrlComponent
- Which part of the URL a component trace refers to.
Constants§
- DEFAULT_
CASE_ SENSITIVE - Apple’s documented default: patterns are case-sensitive.
- DEFAULT_
PERCENT_ ENCODED - Apple’s documented default: patterns are written percent-encoded.
- ISO_
TABLE_ SOURCE - The Foundation release the
$(region)and$(lang)tables were generated from.
Functions§
- diff
- Parses both documents and compares them semantically.
- match_
url - Parses and matches in one call.
- percent_
decode - Percent-decodes
input, leaving invalid escapes untouched. - split_
app_ id - Splits
ABCDE12345.com.example.appinto its application identifier prefix and bundle identifier. - strip_
leading_ slash - The same path without its leading slash, when it has one to spare.
- trim_
path - A path with any trailing run of slashes removed.
- validate
- Parses and validates in one call.
Type Aliases§
- Result
- Convenience alias used across the crate.