In questa sezione

Struttura

Un media URN ha la forma:

media:<type>[;tag=value]...

Esempi:

media:                          # Identità (qualsiasi media)
media:document                  # Un documento, in qualsiasi formato
media:document;ext=pdf          # Un PDF: un documento il cui formato è pdf
media:image                     # Un'immagine, in qualsiasi formato
media:ext=png;image             # Un'immagine PNG
media:enc=utf-8                 # Testo UTF-8 semplice (scalare per default)
media:fmt=json;record           # Oggetto JSON (formato di serializzazione)

Tipo top e tipo unità

L’ordine dei media URN ha due ancore distinte. Non sono intercambiabili, e confonderle capovolge il significato di ogni cap che le usa.

media:: il tipo top

media:

Il solo prefisso, senza tag. Si legge “qualsiasi tipo di dati”.

  • Non ha tag.
  • Ogni altro media URN è conforms_to rispetto a esso.
  • Specificità 0.
  • È il top dell’ordine parziale dei media.
pub const MEDIA_IDENTITY: &str = "media:";
∀m ∈ MediaUrn, m ⪯ media:     (ogni media URN è conforme al top)
media: ⪯ media:               (riflessivo)

Una cap con in=media: dice “accetto qualsiasi input”. Una cap con out=media: dice “posso produrre qualsiasi output”. Usati su entrambi i lati, sono semplicemente i tipi top del tutto generici per gli assi direzionali. Da soli non significano identità.

Nel modello di cap a quattro assi:

  • cap:effect=none è il morfismo identità esplicito
  • cap: e cap:in=media:;out=media: sono forme top nude non ammesse
  • cap:<y-tags> con entrambi i lati direzionali a media: è una trasformazione generica da top a top, non l’identità

media:void: il tipo unità

media:void

Si legge “nessun dato”: il valore nullario, il tipo con esattamente un abitante.

  • Ha il tag marker void.
  • È distinto da media:. Top significa “qui scorre un qualsiasi A”; unit significa “qui scorre (), nessun payload significativo”.
pub const MEDIA_VOID: &str = "media:void";

Una cap con in=media:void non consuma dati; è guidata interamente dai suoi tag non direzionali e da un eventuale stato del peer. Una cap con out=media:void non produce dati; esiste per l’effetto collaterale. Le cap con media:void su entrambi i lati sono puri comandi a effetto collaterale (vedi CapKind: Source, Sink, Effect).

Atomicità

media:void è atomico. Il parser rifiuta qualsiasi media URN che combini il tag marker void con qualsiasi altro tag:

media:void                ✓
media:void;text           ✗  (errore di parsing)
media:void;pdf            ✗  (errore di parsing)
media:void;reason=warmup  ✗  (errore di parsing)
media:void;heartbeat      ✗  (errore di parsing)

Sotto il tipo unità non c’è alcun reticolo. Ammettere raffinamenti creerebbe una tassonomia fittizia di valori unit (media:void;warmup contro media:void;heartbeat ecc.) e la semantica del dispatch si biforcherebbe silenziosamente: sono unit diversi? effetti diversi? comandi diversi? Rifiutare la sintassi chiude la questione.

Quando una cap deve esprimere perché o come usa void, quell’informazione va sull’asse non direzionale del cap URN (o negli argomenti della cap), mai come raffinamento del media URN:

✓ cap:in=media:void;out=media:void;warmup
✓ cap:in=media:void;out=media:void;heartbeat
✓ cap:in=media:void;out=media:image;generate;target=thumbnail

✗ cap:in=media:void;reason=warmup;out=media:void
✗ cap:in=media:void;enc=utf-8;out=media:enc=utf-8

Ciascuna delle prime tre descrive un morfismo distinto (tag di operazione diversi). Le ultime due cercano di inserire la stessa distinzione nel tipo unità stesso; il parser le rifiuta al livello del media URN, prima ancora che il cap URN si formi.

Questa regola è applicata al livello più profondo: ogni costruttore di MediaUrn e ogni percorso di parsing from_string restituisce un errore di parsing in caso di violazione:

Port Errore
Rust MediaUrnError::VoidNotAtomic
Go MediaUrnError{Code: ErrorMediaVoidNotAtomic}
Python MediaUrnError("media:void is atomic …")
Swift/ObjC CSMediaUrnErrorVoidNotAtomic
JS MediaUrnError(VOID_NOT_ATOMIC, …)

Top e unit a colpo d’occhio

Tipo del lato Si legge Usato per
media: “qualsiasi A” wildcard, passthrough generico
media:void ”()” sorgenti, pozzi, effetti
concreto un tipo specifico normale flusso di dati

media: e media:void sembrano superficialmente simili (entrambi sono “non specifici” in un certo senso), ma stanno agli estremi opposti del reticolo dei tipi. media: è il massimo dell’ordine; media:void è una foglia che porta il valore nullario.


Marker semantici e i tre assi dei media

I media URN descrivono i dati con due tipi di tag: i tag marker che dichiarano la modalità o la capacità numerica (numeric, image/visual, audio), e tre assi del media URN ortogonali che descrivono come i byte sono tipizzati, serializzati e codificati.

Non esiste alcun modello di coercizione. Una richiesta di media:enc=utf-8 corrisponde solo a valori che portano il tag enc=utf-8; numeri, booleani e JSON non vengono mai convertiti implicitamente in stringa. Adattare un valore da un formato a un altro (numero → testo, JSON → CSV, testo → PDF) è compito di una capacità di conversione esplicita (ad es. cap:convert-format), mai una proprietà implicita del tipo. Il dispatch fa corrispondere i tipi così come sono dichiarati; non applica coercizioni.

I tre assi dei media

Asse Tag Descrive A valore singolo? Esempi
tipo di file ext=<x> Il tipo di FILE su disco no pdf, png, txt, csv
formato dei dati fmt=<x> Il formato di SERIALIZZAZIONE del contenuto sì (≤ un fmt) json, yaml, ndjson, csv, xml, tsv, psv, cbor, msgpack
codifica enc=<x> La CODIFICA dei caratteri del testo sì utf-8

Questi assi sono indipendenti e non devono essere confusi:

  • ext= è il modo in cui il file si chiama su disco; non dice nulla su come sono strutturati i byte.
  • fmt= è il modo in cui il contenuto è serializzato, una volta guardato all’interno; un valore ha al massimo un fmt.
  • enc= è la codifica dei caratteri, e la sua presenza è ciò che identifica il testo in quanto tale (vedi Rilevamento del tipo). Il testo semplice è media:enc=utf-8.

Quindi un file CSV su disco è media:ext=csv;fmt=csv;..., mentre il contenuto CSV che scorre tra le cap è media:fmt=csv;list;record. Un file di testo semplice è media:ext=txt;enc=utf-8; il testo semplice è soltanto media:enc=utf-8.

Marker standard

Tag Significato Esempi
numeric Supporta operazioni numeriche interi, float
image Un’immagine, da guardare png, jpeg, webp, un fotogramma video
audio Audio, da ascoltare wav, mp3, flac, frame PCM grezzi
video Un video mp4, mov, mkv, webm
document Pagine impaginate, fogli o diapositive pdf, docx, epub, xlsx

image, audio, video e document sono i medium. Ciascuno è un tipo a sé — media:image, media:audio, media:video, media:document — e ogni formato di un medium porta il suo marker, così media:ext=png;image è conforme a media:image e media:document;ext=pdf a media:document. Una cap che prende qualsiasi immagine dichiara media:image; una cap astratta su cap per formato dichiara il medium che condividono. La scrittura tenuta come testo (Markdown, RTF, HTML) è un file di testo e non porta alcun medium.

I marker sono ortogonali ai tre assi. Un numero è media:numeric (senza enc=, perché non viene consegnato come testo). Un booleano consegnato come testo è media:bool;enc=utf-8. Non esiste un marker binary: tutto è binario a livello di byte, quindi “binario” non è una categoria. La domanda significativa è quali assi porta un tipo.

L’adattamento di formato è esplicito

Una capacità che richiede media:enc=utf-8 corrisponde a valori che portano effettivamente il tag enc=utf-8. Non corrisponde a un semplice media:numeric né a media:fmt=json;record. Per passare un numero a una cap che consuma testo, instradalo attraverso una cap di conversione esplicita:

media:numeric ──[cap:convert-format → text]──▶ media:enc=utf-8
media:fmt=json;record ──[cap:convert-format → csv]──▶ media:fmt=csv;list;record

La cap di conversione è un nodo reale del grafo, con i propri tipi di input e di output. Nulla viene adattato alle spalle del dispatcher.


Marker strutturali e valori predefiniti

I media URN non hanno un asse form=. La struttura è rappresentata da tag marker e dall’assenza come valore predefinito:

Proprietà di forma Codifica Significato
scalare nessun tag list Valore singolo (cardinalità predefinita)
lista marker list Collezione ordinata
opaco nessun tag record Nessuna struttura interna chiave-valore (predefinito)
record marker record Struttura chiave-valore

Quindi:

  • media:enc=utf-8 significa scalare + opaco (testo)
  • media:fmt=json;record significa scalare + record
  • media:enc=utf-8;list significa lista + opaco
  • media:fmt=json;list;record significa lista + record

Esempi

media:enc=utf-8                    # Stringa
media:enc=utf-8;list               # Array di stringhe
media:fmt=json;record              # Oggetto JSON
media:integer;list;numeric         # Array di interi

Tipi di media comuni

Primitivi

Media URN Costante Descrizione
media: MEDIA_IDENTITY Top: qualsiasi tipo di dati (wildcard universale)
media:void MEDIA_VOID Unit: il valore nullario (qui non scorre alcun dato)
media:enc=utf-8 MEDIA_STRING Stringa UTF-8
media:integer;numeric MEDIA_INTEGER Intero
media:numeric MEDIA_NUMBER Float
media:bool;enc=utf-8 MEDIA_BOOLEAN Booleano
media:record MEDIA_OBJECT Record/oggetto generico
media:fmt=json;record MEDIA_JSON Oggetto JSON

Array

Media URN Costante Descrizione
media:enc=utf-8;list MEDIA_STRING_LIST Array di stringhe
media:integer;list;numeric MEDIA_INTEGER_LIST Array di interi
media:list;numeric MEDIA_NUMBER_LIST Array di numeri
media:bool;enc=utf-8;list MEDIA_BOOLEAN_LIST Array di booleani
media:list;record MEDIA_OBJECT_LIST Lista di record opachi

Medium e i loro formati

Media URN Costante Descrizione
media:image MEDIA_IMAGE Un’immagine in qualsiasi formato
media:ext=png;image MEDIA_PNG Immagine PNG
media:ext=jpeg;image MEDIA_JPEG Immagine JPEG
media:audio MEDIA_AUDIO Audio in qualsiasi formato
media:audio;ext=wav MEDIA_WAV Audio WAV
media:video MEDIA_VIDEO Un video in qualsiasi contenitore
media:ext=mp4;video MEDIA_MP4 Video MP4
media:document MEDIA_DOCUMENT Un documento in qualsiasi formato
media:document;ext=pdf MEDIA_PDF Documento PDF

Semantica della corrispondenza

La corrispondenza tra media URN segue la semantica dei tagged URN descritta in Dominio dei tagged URN.

Corrispondenza di pattern

Pattern:  media:document
Istanza:  media:document;ext=pdf

L'istanza ha tutti i tag richiesti dal pattern?
- Il pattern richiede: document=*
- L'istanza ha: document=*, ext=pdf
- document presente? Sì → CORRISPONDE ✓

Specificità

Più tag = più specifico:

spec(media:) = 0
spec(media:document) = 2             # document=* è must-have-any
spec(media:document;ext=pdf) = 6     # must-have-any (2) + valore esatto (4)
spec(media:document;ext=pdf;list) = 8

Conformità

media:document;ext=pdf ⪯ media:document   (un pdf è un documento)
media:document ⪯ media:                   (un documento è conforme all'identità)
media:document;ext=pdf ⪯ media:image      ✗ (non sulla stessa catena)

Specifiche di direzione nei cap URN

Quando sono usati come valori di in o out nei cap URN:

Quotatura

I media URN che contengono ; devono essere racchiusi tra virgolette:

cap:in="media:document;ext=pdf";extract;out="media:record"

Espansione dell’identità

in=* e out=* si espandono in media::

cap:in=*;convert;out=*
→ cap:in=media:;convert;out=media:

Dispatch

Per il dispatch (vedi Dispatch):

  • Input: l’input della richiesta deve essere conforme all’input del candidato (controvariante)
  • Output: l’output del candidato deve essere conforme all’output della richiesta (covariante)

Rilevamento del tipo

Metodi di supporto

let urn = MediaUrn::from_string("media:fmt=json;record")?;

urn.is_json()    // true se e solo se get_tag("fmt") == Some("json")
urn.is_yaml()    // true se e solo se get_tag("fmt") == Some("yaml")
urn.is_csv()     // true se e solo se get_tag("fmt") == Some("csv")
urn.is_void()    // true se e solo se è presente il tag marker `void` (tipo unità)
urn.is_top()     // true se e solo se l'URN non ha alcun tag (tipo top)

I predicati di formato (is_json / is_yaml / is_csv) leggono l’asse fmt=: ciascuno è semplicemente get_tag("fmt") == Some(<format>). Non esistono is_text() né is_binary(). Tutto è binario a livello di byte, quindi “testo contro binario” non è una vera distinzione. Il testo è identificato dalla presenza del tag enc=:

urn.has_tag("enc")          // true → questo valore è testo
urn.get_tag("enc")          // Some("utf-8") → la codifica, se presente

Non esiste un metodo is_utf8; chi chiama esamina direttamente get_tag("enc").

is_void e is_top sono i predicati che il classificatore CapKind consulta. Insieme permettono a qualsiasi chiamante di stabilire se un media URN è un tipo concreto, il wildcard o il tipo unità senza analizzare stringhe.

Interrogazioni sui tag

urn.has_tag("enc")          // true (testo)
urn.has_tag("fmt")          // true (serializzato)
urn.has_tag("list")         // false
urn.has_tag("record")       // true

Aggiungere nuovi tipi

Quando si definisce un nuovo tipo di media:

  1. Stabilisci il formato del contenuto (fmt=) e/o la codifica (enc=): come è serializzato questo valore, ed è testo?
  2. Stabilisci struttura/cardinalità: scalare predefinito oppure list, opaco predefinito oppure record
  3. Aggiungi una costante se usato di frequente
  4. Documentalo nel catalogo dei media

Esempio: tipo personalizzato

// Un nuovo tipo per log strutturati (serializzati come JSON)
const MEDIA_LOG_ENTRY: &str = "media:log-entry;fmt=json;record";

// Serializzato come JSON, strutturato come record

Posizione nell’ordine parziale

I media URN formano un ordine parziale (ordine di specializzazione). media: è l’unico top; media:void è una foglia, distinta da ogni tipo concreto:

                    media:                          (top — qualsiasi A)
                  /        \
          media:enc=utf-8   media:void               (foglia — unit ())
            /         \
  media:integer;numeric  media:fmt=json;record
                                      |
                         media:fmt=json;list;record

Più tag = più in basso nell’ordine = più specifico. media:void porta esattamente un tag (void) e quindi ha specificità 2 (un tag must-have-any, più il prefisso); non è un raffinamento di alcun tipo concreto.


Riepilogo

Concetto Definizione
Struttura media:<type>[;tag=value]...
Top media:: wildcard universale, massimo dell’ordine parziale, “qualsiasi A”
Unit media:void: valore nullario, foglia dell’ordine parziale, “()”
Assi dei media ext= (tipo di file), fmt= (serializzazione), enc= (codifica)
Marker semantici numeric, visual/image, audio, video
Marker strutturali list e record; scalare e opaco sono i valori predefiniti per assenza
Corrispondenza Semantica dei tagged URN (tabella di verità)
Specificità Somma dei punteggi dei singoli tag

I media URN descrivono tipi di dati. Sono usati:

  • Nelle specifiche in/out dei cap URN (dove la scelta tra media:, media:void e un tipo concreto determina il tipo della cap)
  • Come identificatori di argomenti
  • Per la corrispondenza dei tipi nel dispatch