Skip to main content

TraceHeader

Struct TraceHeader 

Source
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: String

MoQT version identifier (e.g. "moq-transport-17", "moq-transport-rfc9999").

§perspective: Perspective

Recording viewpoint.

§detail: DetailLevel

Detail level.

§start_time: u64

Recording 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

Source

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.

Source

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

Source§

fn clone(&self) -> TraceHeader

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TraceHeader

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<&TraceHeader> for Value

Source§

fn from(h: &TraceHeader) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for TraceHeader

Source§

fn eq(&self, other: &TraceHeader) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for TraceHeader

Source§

impl TryFrom<Value> for TraceHeader

Source§

type Error = MoqTraceError

The type returned in the event of a conversion error.
Source§

fn try_from(value: Value) -> Result<Self, MoqTraceError>

Performs the conversion.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.