mcproto_types/contextual.rs
1//! Context used by protocol values whose wire representation depends on their
2//! enclosing packet or data structure.
3
4/// External information required to encode or decode a contextual value.
5///
6/// The initial context records whether the current field is present. This is
7/// intended for protocol fields described as `Optional X`, where no presence
8/// marker is encoded and the field's presence must be known from its enclosing
9/// packet or data structure.
10///
11/// A `Context` does not consume or produce any bytes. The enclosing codec must
12/// derive it from already-known protocol state and pass it to
13/// [`ContextualCodec`](crate::ContextualCodec).
14///
15/// # Examples
16///
17/// ```
18/// use mcproto_types::contextual::Context;
19///
20/// let has_signature = true; // Derived from an earlier packet field.
21/// let context = Context::new(has_signature);
22/// assert!(context.is_present());
23/// assert!(!Context::absent().is_present());
24/// ```
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
26pub struct Context {
27 present: bool,
28}
29
30impl Context {
31 /// Context for a field that is present on the wire.
32 pub const PRESENT: Self = Self::new(true);
33
34 /// Context for a field that occupies zero bytes on the wire.
35 pub const ABSENT: Self = Self::new(false);
36
37 /// Creates a context from a presence condition determined by the enclosing
38 /// protocol structure.
39 #[must_use]
40 pub const fn new(present: bool) -> Self {
41 Self { present }
42 }
43
44 /// Creates context for a field that is present on the wire.
45 #[must_use]
46 pub const fn present() -> Self {
47 Self::PRESENT
48 }
49
50 /// Creates context for a field that occupies zero bytes on the wire.
51 #[must_use]
52 pub const fn absent() -> Self {
53 Self::ABSENT
54 }
55
56 /// Returns whether the contextual field is present on the wire.
57 #[must_use]
58 pub const fn is_present(&self) -> bool {
59 self.present
60 }
61}