pub struct TraceHeader {Show 13 fields
pub protocol: String,
pub perspective: Perspective,
pub detail: DetailLevel,
pub start_time: u64,
pub end_time: Option<u64>,
pub transport: Option<String>,
pub source: Option<String>,
pub endpoint: Option<String>,
pub session_id: Option<String>,
pub segment: Option<SegmentInfo>,
pub sampling: Option<SamplingInfo>,
pub custom: Option<BTreeMap<String, Value>>,
pub extra: Vec<(Value, Value)>,
}Expand description
Session metadata written at the start of a .moqtrace file, and at the
start of every segment in a segmented one.
Fields§
§protocol: StringMoQT version identifier (e.g. "moq-transport-17", "moq-transport-rfc9999").
perspective: PerspectiveRecording viewpoint.
detail: DetailLevelDetail level.
start_time: u64Recording start time (Unix epoch milliseconds). In a segmented trace this is the segment’s start, not the stream’s.
end_time: Option<u64>Recording end time (Unix epoch milliseconds). Set when the trace is finalized, so a crash-truncated file has none.
transport: Option<String>Transport type (e.g. "webtransport", "raw-quic").
source: Option<String>Software that produced the trace. Also namespaces the source-local peer identifiers carried on events.
endpoint: Option<String>Remote peer URI.
session_id: Option<String>Capture-correlation identifier, grouping traces of one logical session recorded from different vantage points.
segment: Option<SegmentInfo>Per-segment metadata. Present only when this header begins one segment of a segmented stream.
sampling: Option<SamplingInfo>Sampling and filter metadata. Present only when events were dropped or filtered at the source.
custom: Option<BTreeMap<String, Value>>User-defined metadata. "payloadMasked": true here declares that
payload bytes were zeroed before writing.
None when the file carried no "custom" — and also when it carried
one this map cannot hold exactly: a "custom" that is not a map, or
one with a key that is not text, in which case the whole value is kept
verbatim in TraceHeader::extra. Losing typed access is the smaller
harm; nothing in the format gives "custom" keys meaning, so there is
nothing to lose but convenience, and the bytes survive.
A "custom" carrying one key twice takes the same route, a BTreeMap
being unable to hold it either. That one is kept whole on the way in
and written with the repeat dropped: a writer may not emit a map with a
repeated key, so a rewrite keeps the first entry rather than both. See
TraceHeader::extra.
"custom" has no store of its own. Every key in it belongs to whoever
wrote the trace, so there is no such thing as an unrecognised key
there: it is a passthrough, handed back key for key and written back
as it was handed over — the value, not its encoding, which the two
rules in TraceHeader::extra apply to here as well.
extra: Vec<(Value, Value)>Keys in the header map that this version of the crate could not use, kept verbatim.
A key the format does not define lands here, and so does a key it
does define carrying a value this crate cannot use — "transport": 42, an "endTime" with a fractional part, a "segment" that is not a
map. Knowing more about a key must not mean preserving it less: the
value is ignored for meaning, the field that would have held it reads
None, and the entry is written back unchanged after the header’s own
keys.
Dropping such a key instead would emit a valid file that looks as though it never carried it, and the tools that read a trace and write it back — a redaction pass, a filter, a re-segmentation — are exactly the ones a trace passes through on its way to someone else.
“Unchanged” binds the value and not its encoding. On the way out, an
integral float in a stored value is written as a CBOR integer and a
byte string under RFC 8746’s tag 64 as major type 2, at any depth,
because SPEC.md’s two encoding rules are about every byte this crate
emits rather than only the keys it understood — the JavaScript
implementation’s decoder folds both shapes away before its own code
sees them, so it could not emit either from a store however hard it
tried. Nothing a comparison of the two values can see changes, with the
single exception SPEC.md names: -0.0 written as 0 loses its sign.
A CBOR map may not carry one key twice, and this list can: it is an ordered list of pairs, not a map, whether it was populated by hand or from a file whose header repeated a key. So on the way out an entry naming a key the header writes from a field is dropped, and of two entries sharing a key the first is written — as it is for a map nested inside a stored value, which is a map this crate emits too.
This is the header map’s store only. SegmentInfo::extra and
SamplingInfo::extra keep their own, because a private key on
"segment" and a key of the same name at the top level are different
keys.
Empty for every header this crate constructs itself.
Implementations§
Source§impl TraceHeader
impl TraceHeader
Sourcepub fn new(
protocol: impl Into<String>,
perspective: Perspective,
detail: DetailLevel,
start_time: u64,
) -> Self
pub fn new( protocol: impl Into<String>, perspective: Perspective, detail: DetailLevel, start_time: u64, ) -> Self
A header carrying only the four required fields.
Prefer this over a struct literal and assign the optional fields you need: a literal has to be edited every time the format gains a field, this does not.
Sourcefn writes_key(&self, key: &str) -> bool
fn writes_key(&self, key: &str) -> bool
Whether key is written from one of the header map’s own fields —
equivalently, on a header that was decoded, whether the decode used it.
The "segment" and "sampling" maps answer for their own keys.
Deliberately not “does the format define key”. The two part company
on a defined key whose value the decode could not use: such a key is
treated as unrecognised, so its field stays None and the entry goes
to TraceHeader::extra, from where the encoder writes it back
unchanged. Asking about the format’s whole vocabulary instead would
keep the key out of extra while no field holds it either, and merely
reading the file would delete the value.
The destructuring is exhaustive on purpose — no .. — so a new field
does not compile until it is answered for here. Both ways of getting
the answer wrong are silent: a field left out has its key written
twice, once from the field and once from extra, and a CBOR map with
a duplicate key is malformed; a key wrongly claimed is dropped from
every rewrite.
Trait Implementations§
Source§impl Clone for TraceHeader
impl Clone for TraceHeader
Source§fn clone(&self) -> TraceHeader
fn clone(&self) -> TraceHeader
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more