pub struct Region(/* private fields */);Expand description
A region code that has already passed is_valid_region, stored in the
normalized (uppercase, untrimmed-of-nothing) form.
The point of the type is that the normalization is done ONCE, at the parse
boundary, instead of at every comparison site. A raw String carrying “an
ISO 3166-1 alpha-2 code” by doc comment alone leaves each consumer to
re-derive that: decdn-client’s candidate ranking was trimming and
case-folding on every comparison because one side came normalized from
config and the other raw from the chain, and structural Eq on the
containing type was wrong as a result — " us " and "US" compared
unequal (#1348).
Two bytes, Copy, and bounded by construction — which also caps what an
operator-submitted regionHint can cost on a deserialize path, where the
on-chain source permits any string up to 16 bytes.
Serializes as the plain 2-character string, so persisted forms stay
human-readable and a Region field is wire-compatible with the String it
replaces in the serialize direction.
Implementations§
Source§impl Region
impl Region
Sourcepub fn parse(raw: &str) -> Option<Self>
pub fn parse(raw: &str) -> Option<Self>
Parse raw into a Region, or None if it is not an accepted code.
Surrounding whitespace is trimmed and the code is uppercased before the
allowlist check, because both sources this reads from are
operator-submitted: a config file and an on-chain regionHint the
contract does not constrain beyond a length cap.
None rather than an error type: for the advisory uses (locality-aware
node ranking) an unrecognized code means “no locality information”, not
“reject this node”. Callers that need it to be fatal — config
resolution — say so at their own layer.
Trait Implementations§
impl Copy for Region
Source§impl Debug for Region
Hand-written so the code renders as text, not as its bytes. A derived
Debug over the [u8; 2] payload prints Region([85, 83]), and this type
IS formatted with {:?} on an operator-facing path — decdn get’s
“discovered node … (region {:?})” line — as well as into tracing fields
and anyhow context. The derive turned that line’s output from "US" into
Some(Region([85, 83])).
impl Debug for Region
Hand-written so the code renders as text, not as its bytes. A derived
Debug over the [u8; 2] payload prints Region([85, 83]), and this type
IS formatted with {:?} on an operator-facing path — decdn get’s
“discovered node … (region {:?})” line — as well as into tracing fields
and anyhow context. The derive turned that line’s output from "US" into
Some(Region([85, 83])).
Source§impl<'de> Deserialize<'de> for Region
Deserializing re-runs the allowlist, so the invariant holds for values that
arrive from a file or the wire rather than through Region::parse — a
derived impl over the byte array would let any two bytes in.
impl<'de> Deserialize<'de> for Region
Deserializing re-runs the allowlist, so the invariant holds for values that
arrive from a file or the wire rather than through Region::parse — a
derived impl over the byte array would let any two bytes in.
Deserializes an owned String rather than a borrowed &str so this works
against non-borrowing formats too (a serde_json reader, postcard over a
streamed buffer); the allocation is bounded by the caller’s own input and
dropped immediately.
Source§fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error>
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error>
impl Eq for Region
Source§impl FromStr for Region
Rejects with the same allowlist Region::parse applies. The error carries
no input — a region code reaches log fields and metric labels, and this type
exists partly to keep unvalidated bytes out of them. The Deserialize impl
below upholds the same property, so it holds for every fallible construction
path, not just this one.
impl FromStr for Region
Rejects with the same allowlist Region::parse applies. The error carries
no input — a region code reaches log fields and metric labels, and this type
exists partly to keep unvalidated bytes out of them. The Deserialize impl
below upholds the same property, so it holds for every fallible construction
path, not just this one.