Decoder Rules
mosaicolabs.bridges.mcap.decoders.rule ¶
FieldStep
dataclass
¶
Descend into container[name] — a struct field lookup (a decoded protobuf submessage dict, keyed by field name).
ListStep
dataclass
¶
Fan out over every element of the list found at this position (a decoded repeated
field). As the last step, the list itself is the container and each index is the key
(the rule's callback runs once per element); otherwise the remaining steps are resolved
independently against each element.
MapValuesStep
dataclass
¶
Fan out over every value of the map dict found at this position (a decoded protobuf
map<K, V> field). Unlike FieldStep, does not look up one named key — a map's keys are
arbitrary data, not schema-known field names. As the last step, the map dict itself is
the container and each key addresses one value; otherwise the remaining steps are
resolved independently against each value.
Rule
dataclass
¶
Bases: Generic[T]
A single postprocessing rule, applied by MCAPMsgDecoderBase._postprocess() to
fix up one specific field of a decoded message dict so it complies with
the target PyArrow schema.
A Rule is used in two stages:
- Schema inspection, during
register_schema(): an encoding-specific matcher (e.g.ProtobufRulesMatcher.from_descriptor) walks the schema and, for every field whose schema node satisfiespredicate(checked viais_respected), associates that field'sRulePathwith thisRule. The result is aDict[RulePath, List[Rule]](MCAPMsgDecoderBase._field_rule_mapper) mapping each field path to everyRulematched for it — a field can satisfy more than one predicate (e.g. aTimestampfield that is also aoneofmember), in which case all of them apply, inPROTOBUF_RULESorder. - Postprocessing, during
decode():MCAPMsgDecoderBase._postprocess()iterates that mapping and callsrule.apply(data, path)for every(path, rule)pair, so eachcallbackruns only on the specific fieldpathits rule was matched against — never on the rest of the decoded dict. If a field is absent andcallbackraisesKeyErrorto signal that,apply()logs it and moves on, so a sibling rule registered for the same path (e.g. a_fill_absent_fieldfallback) still gets to run. A field that is present butNone(e.g. already filled in by_fill_absent_field) is left untouched by every transforming callback.
is_respected ¶
Whether this rule's predicate matches node (a schema node, e.g. a protobuf
FieldDescriptor), meaning this rule should be registered for that field.
apply ¶
Resolves path against data, fanning out at every ListStep/MapValuesStep,
and invokes callback(container, key) once per (container, key) pair path
resolves to. This is what MCAPMsgDecoderBase._postprocess() calls for every rule
registered against a given field path.
callback may raise KeyError to signal that the field it needs is absent (e.g.
_coerce_int64_field on a field MessageToDict omitted); that's caught and logged at
debug level rather than propagated, so it never aborts postprocessing of the rest of
data. A field that is present but None is not an error: callback leaves it
untouched.
match_rules ¶
Returns every rule in rules whose predicate matches node, in the same relative
order as rules. Returns None, not an empty list, if no rule applies.