1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! # Codec Trait and Negotiation Helper
//!
//! This module defines the core [`Codec`] trait that all encoding backends
//! must implement, along with the [`CodecExt`] extension trait that adds
//! generic convenience methods. The standalone [`negotiate`] function
//! performs server-side codec selection from the client's preference list.
//!
//! ## Trait Design
//!
//! [`Codec`] intentionally uses non-generic `encode_value` / `decode_value`
//! signatures so the trait remains dyn-compatible (object-safe). Generic
//! wrappers that serialize and deserialize Rust types via `serde_json::Value`
//! are provided by [`CodecExt`], which is blanket-implemented for every
//! `Codec` implementor.
use Arc;
use Bytes;
use Serialize;
use crateResult;
use crateCodec as FrameCodec;
/// Trait for a single named encoding format.
///
/// Codecs are expected to be stateless and cheaply cloneable. Each codec
/// is identified by a [`FrameCodec`] tag so that both peers can agree on
/// which encoding to use during the Hello handshake.
///
/// The trait is dyn-compatible (object-safe) because `encode_value` and
/// `decode_value` operate on `serde_json::Value` rather than generic types.
/// For generic convenience methods, see [`CodecExt`].
/// Blanket implementation of [`CodecExt`] for every type that implements
/// [`Codec`], providing generic encode/decode helpers.
/// Extension methods available on every [`Codec`] implementation.
///
/// These generic helpers serialize Rust types into [`serde_json::Value`]
/// (via `serde_json::to_value`) before delegating to the non-generic
/// [`Codec::encode_value`], and perform the reverse path for decoding.
///
/// This trait is blanket-implemented for all `Codec + ?Sized`, so there
/// is no need to implement it manually.
/// Negotiate a codec given a list of server-registered codecs and the
/// client's ordered preferences.
///
/// The function iterates through the client's preference list in order
/// and returns the first codec whose [`FrameCodec`] tag matches one of
/// the server's registered codecs.
///
/// # Arguments
///
/// * `server` -- The codecs the server has registered, wrapped in [`Arc`].
/// * `client` -- The client's ordered list of preferred [`FrameCodec`] tags.
///
/// # Returns
///
/// The first mutually supported codec, or a
/// [`FrameReject::CodecUnsupported`](crate::error::FrameReject::CodecUnsupported)
/// error if no common codec is found.
///
/// # Errors
///
/// Returns [`RiftError::Frame`](crate::error::RiftError::Frame) when no
/// overlap exists between the server and client codec sets.