Table of Contents

Interface IReferenceCode<TSelf>

Namespace
DatabentoDotNet.Reference
Assembly
DatabentoDotNet.Reference.dll

The contract the ten reference code types share: a wrapper over the wire string that keeps a code this library does not know instead of losing it.

public interface IReferenceCode<TSelf> where TSelf : struct, IReferenceCode<TSelf>

Type Parameters

TSelf

The implementing type.

Remarks

Ten of the reference enums are open sets, and a C# enum cannot represent one. Upstream ends each of them in an Unknown(String) variant whose FromStr falls through to it (enums.rs:1139 and its siblings), so an ISO code Databento adds next month round-trips through that library untouched. The two obvious .NET answers both give that up:

An enum with an Unknown = -1 member compiles and loses the string — a caller handed Country.Unknown cannot tell Kosovo from a typo and cannot echo the value back into a filter, which is strictly worse than upstream on the axis upstream chose. A bare string is free and gives up every misuse check: nothing would stop a Currency reaching a countries filter.

So each type is a readonly record struct over the code, with the known values as static members — Country.Us still reads like an enum at a call site. record struct rather than a hand-rolled wrapper is deliberate: it synthesizes Equals(object) and GetHashCode() that agree with each other over the wrapped string, which a hand-rolled struct gets wrong by default.

Which types are open is decided by where the vocabulary comes from, not by upstream's syntax. A single-byte alphabet is closed, because a new value in it is a wire-format change; a code that comes out of Databento's growing data dictionary is not. Probing corporate_actions.list_enums found upstream already behind the live server on two of the sets it models as closed — SecurityType at 30 of 64 and Frequency at 14 of 16 — and OutturnStyle is here beside them despite being exact against the server today, because the rule is about where a vocabulary comes from rather than how many values it currently holds. That is a behavioural departure from upstream and goes one way only: this library accepts rows upstream rejects, never the reverse. ROADMAP.md §6 records it, along with the third set the probe found upstream stale on — Event, which is absent from this sentence because upstream already models it as open.

default means "no value", and that is what a blank code deserializes to. The dictionary itself carries blank entries — SECTYPE, FREQ and EVENTSUBTYPE each have one, and 148 of the 235 groups do — so a blank is a real thing the server sends rather than a malformed value. From(string?) maps it to default, whose Code is null and whose HasValue is false. The constructor refuses one, so the only way to reach that state is deliberately.

Properties

Code

The wire code, or null when this names no value.

string? Code { get; }

Property Value

string

HasValue

true when this names a code — known or not.

bool HasValue { get; }

Property Value

bool

IsKnown

true when Code is one of KnownCodes.

bool IsKnown { get; }

Property Value

bool

Remarks

false is not an error. It means the server sent something newer than the table this library shipped with, and the code is still in Code to be read, logged, or sent back in a filter.

KnownCodes

Every code the reference API reported for this type when the vendored fixture was captured.

public static abstract IReadOnlySet<string> KnownCodes { get; }

Property Value

IReadOnlySet<string>

Remarks

A snapshot, not a closed set. IsKnown answers against it; nothing rejects a code outside it.

Methods

From(string?)

Reads a wire code, mapping null and the empty string to default.

public static abstract TSelf From(string? code)

Parameters

code string

The wire code, or null.

Returns

TSelf

The value.