Media URNs
Media type system, coercion tags, form tags, matching semantics, and type catalogue
Structure
A Media URN has the form:
media:<type>[;tag=value]...
Examples:
media: # Identity (any media)
media:pdf # PDF type
media:pdf;bytes # PDF with bytes marker
media:textable;form=scalar # String type
media:image;subtype=png;visual # PNG image
The Identity
The media identity is:
media:
This URN:
- Has no tags
- Represents “any media type”
- Is the top of the media partial order
- Has specificity 0
pub const MEDIA_IDENTITY: &str = "media:";
Properties:
All media URNs conform to the identity.
Coercion Tags
Media URNs use coercion tags to declare type capabilities. These enable polymorphic matching.
Standard Coercion Tags
| Tag | Meaning | Examples |
|---|---|---|
textable |
Can be represented as UTF-8 text | strings, numbers, booleans, JSON |
binary |
Raw bytes representation | images, PDFs, audio |
numeric |
Supports numeric operations | integers, floats |
scalar |
Single atomic value | primitives (not arrays/objects) |
sequence |
Ordered collection | arrays |
map |
Key-value structure | objects |
visual |
Has visual rendering | images, PDFs |
How Coercion Works
A capability requiring media:textable matches ANY type with the textable tag:
cap:in="media:textable";op=prompt;out="media:textable;form=map"
This matches:
media:textable;form=scalar(string)media:integer(if it has textable)media:bool;textable;form=scalar(boolean)media:textable;form=map(object via JSON.stringify)
Coercion Rules
| Source Type | Can Coerce To | Method |
|---|---|---|
| integer, number | textable | .toString() |
| boolean | textable | "true" / "false" |
| object, array | textable | JSON stringify |
| string | textable | Direct (already text) |
| image, PDF, audio | textable | NO (requires explicit conversion cap) |
Form Tags
The form tag specifies structural shape:
| Value | Meaning |
|---|---|
form=scalar |
Single value |
form=list |
Array/sequence |
form=map |
Object/dictionary |
Examples
media:textable;form=scalar # String
media:textable;form=list # Array of strings
media:textable;form=map # JSON object
media:integer;textable;form=list # Array of integers
Common Media Types
Primitives
| Media URN | Constant | Description |
|---|---|---|
media: |
MEDIA_IDENTITY |
Any/raw binary |
media:void |
MEDIA_VOID |
No data |
media:textable;form=scalar |
MEDIA_STRING |
UTF-8 string |
media:integer |
MEDIA_INTEGER |
Integer |
media:textable;numeric;form=scalar |
MEDIA_NUMBER |
Float |
media:bool;textable;form=scalar |
MEDIA_BOOLEAN |
Boolean |
media:textable;form=map |
MEDIA_OBJECT |
JSON object |
Arrays
| Media URN | Constant | Description |
|---|---|---|
media:textable;form=list |
MEDIA_STRING_ARRAY |
String array |
media:integer;textable;form=list |
MEDIA_INTEGER_ARRAY |
Integer array |
media:textable;numeric;form=list |
MEDIA_NUMBER_ARRAY |
Number array |
media:bool;textable;form=list |
MEDIA_BOOLEAN_ARRAY |
Boolean array |
Visual Types
| Media URN | Description |
|---|---|
media:image;subtype=png;visual |
PNG image |
media:image;subtype=jpeg;visual |
JPEG image |
media:application;subtype=pdf;visual |
PDF document |
Matching Semantics
Media URN matching follows Tagged URN semantics from URN Syntax.
Pattern Matching
Pattern: media:bytes
Instance: media:pdf;bytes
Does instance have all tags pattern requires?
- Pattern requires: bytes=*
- Instance has: pdf=*, bytes=*
- bytes present? Yes → MATCH ✓
Specificity
More tags = more specific:
Conformance
Direction Specs in Cap URNs
When used as in or out values in Cap URNs:
Quoting
Media URNs containing ; must be quoted:
cap:in="media:pdf;bytes";op=extract;out="media:object"
Identity Expansion
in=* and out=* expand to media::
cap:in=*;op=convert;out=*
→ cap:in=media:;op=convert;out=media:
Dispatch
For dispatch (see Dispatch):
- Input: Request input must conform to provider input (contravariant)
- Output: Provider output must conform to request output (covariant)
Partial Order
Media URNs form a partial order (specialization order):
graph TD
A["media:"] --> B["media:textable"]
B --> C["media:textable;form=scalar"]
B --> D["media:textable;form=map"]
C --> E["media:integer;textable"]
D --> F["media:json;textable;form=map"]
style A fill:none,stroke:#888
style E fill:none,stroke:#888
style F fill:none,stroke:#888
More tags = lower in the order = more specific.
Type Detection
Helper Methods
let urn = MediaUrn::from_string("media:textable;form=scalar")?;
urn.is_text() // true for string, text/*
urn.is_json() // true for object, object-array
urn.is_binary() // true for raw binary, images
Tag Queries
urn.has_tag("textable") // true
urn.tag_value("form") // Some("scalar")
Adding New Types
When defining a new media type:
- Determine coercion tags: What can this type be coerced to?
- Determine form: scalar, list, or map?
- Add constant if frequently used
- Document in media catalogue
// A new type for structured logs
const MEDIA_LOG_ENTRY: &str = "media:log-entry;textable;form=map";
// Coercible to text (via JSON), structured as map
Summary
| Concept | Definition |
|---|---|
| Structure | media:<type>[;tag=value]... |
| Identity | media: (any media, top of partial order) |
| Coercion tags | textable, binary, numeric, scalar, sequence, map, visual |
| Form tag | scalar, list, map |
| Matching | Tagged URN semantics (truth table) |
| Specificity | Sum of per-tag scores |
Media URNs describe data types. They are used:
- In Cap URN
in/outspecs - As argument identifiers
- For type matching in dispatch