Coverage Report

Created: 2025-11-16 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-0.13.0/src/codec/mod.rs
Line
Count
Source
1
//! Generic encoding and decoding.
2
//!
3
//! This module contains the generic `Codec`, `Encoder` and `Decoder` traits
4
//! and a protobuf codec based on prost.
5
6
mod buffer;
7
pub(crate) mod compression;
8
mod decode;
9
mod encode;
10
#[cfg(feature = "prost")]
11
mod prost;
12
13
use crate::Status;
14
use std::io;
15
16
pub use self::buffer::{DecodeBuf, EncodeBuf};
17
pub use self::compression::{CompressionEncoding, EnabledCompressionEncodings};
18
pub use self::decode::Streaming;
19
pub use self::encode::EncodeBody;
20
#[cfg(feature = "prost")]
21
pub use self::prost::ProstCodec;
22
23
/// Unless overridden, this is the buffer size used for encoding requests.
24
/// This is spent per-rpc, so you may wish to adjust it. The default is
25
/// pretty good for most uses, but if you have a ton of concurrent rpcs
26
/// you may find it too expensive.
27
const DEFAULT_CODEC_BUFFER_SIZE: usize = 8 * 1024;
28
const DEFAULT_YIELD_THRESHOLD: usize = 32 * 1024;
29
30
/// Settings for how tonic allocates and grows buffers.
31
///
32
/// Tonic eagerly allocates the buffer_size per RPC, and grows
33
/// the buffer by buffer_size increments to handle larger messages.
34
/// Buffer size defaults to 8KiB.
35
///
36
/// Example:
37
/// ```ignore
38
/// Buffer start:       | 8kb |
39
/// Message received:   |   24612 bytes    |
40
/// Buffer grows:       | 8kb | 8kb | 8kb | 8kb |
41
/// ```
42
///
43
/// The buffer grows to the next largest buffer_size increment of
44
/// 32768 to hold 24612 bytes, which is just slightly too large for
45
/// the previous buffer increment of 24576.
46
///
47
/// If you use a smaller buffer size you will waste less memory, but
48
/// you will allocate more frequently. If one way or the other matters
49
/// more to you, you may wish to customize your tonic Codec (see
50
/// codec_buffers example).
51
///
52
/// Yield threshold is an optimization for streaming rpcs. Sometimes
53
/// you may have many small messages ready to send. When they are ready,
54
/// it is a much more efficient use of system resources to batch them
55
/// together into one larger send(). The yield threshold controls how
56
/// much you want to bulk up such a batch of ready-to-send messages.
57
/// The larger your yield threshold the more you will batch - and
58
/// consequently allocate contiguous memory, which might be relevant
59
/// if you're considering large numbers here.
60
/// If your server streaming rpc does not reach the yield threshold
61
/// before it reaches Poll::Pending (meaning, it's waiting for more
62
/// data from wherever you're streaming from) then Tonic will just send
63
/// along a smaller batch. Yield threshold is an upper-bound, it will
64
/// not affect the responsiveness of your streaming rpc (for reasonable
65
/// sizes of yield threshold).
66
/// Yield threshold defaults to 32 KiB.
67
#[derive(Clone, Copy, Debug)]
68
pub struct BufferSettings {
69
    buffer_size: usize,
70
    yield_threshold: usize,
71
}
72
73
impl BufferSettings {
74
    /// Create a new `BufferSettings`
75
0
    pub fn new(buffer_size: usize, yield_threshold: usize) -> Self {
76
0
        Self {
77
0
            buffer_size,
78
0
            yield_threshold,
79
0
        }
80
0
    }
81
}
82
83
impl Default for BufferSettings {
84
0
    fn default() -> Self {
85
0
        Self {
86
0
            buffer_size: DEFAULT_CODEC_BUFFER_SIZE,
87
0
            yield_threshold: DEFAULT_YIELD_THRESHOLD,
88
0
        }
89
0
    }
90
}
91
92
// 5 bytes
93
const HEADER_SIZE: usize =
94
    // compression flag
95
    std::mem::size_of::<u8>() +
96
    // data length
97
    std::mem::size_of::<u32>();
98
99
// The default maximum uncompressed size in bytes for a message. Defaults to 4MB.
100
const DEFAULT_MAX_RECV_MESSAGE_SIZE: usize = 4 * 1024 * 1024;
101
const DEFAULT_MAX_SEND_MESSAGE_SIZE: usize = usize::MAX;
102
103
/// Trait that knows how to encode and decode gRPC messages.
104
pub trait Codec {
105
    /// The encodable message.
106
    type Encode: Send + 'static;
107
    /// The decodable message.
108
    type Decode: Send + 'static;
109
110
    /// The encoder that can encode a message.
111
    type Encoder: Encoder<Item = Self::Encode, Error = Status> + Send + 'static;
112
    /// The encoder that can decode a message.
113
    type Decoder: Decoder<Item = Self::Decode, Error = Status> + Send + 'static;
114
115
    /// Fetch the encoder.
116
    fn encoder(&mut self) -> Self::Encoder;
117
    /// Fetch the decoder.
118
    fn decoder(&mut self) -> Self::Decoder;
119
}
120
121
/// Encodes gRPC message types
122
pub trait Encoder {
123
    /// The type that is encoded.
124
    type Item;
125
126
    /// The type of encoding errors.
127
    ///
128
    /// The type of unrecoverable frame encoding errors.
129
    type Error: From<io::Error>;
130
131
    /// Encodes a message into the provided buffer.
132
    fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error>;
133
134
    /// Controls how tonic creates and expands encode buffers.
135
0
    fn buffer_settings(&self) -> BufferSettings {
136
0
        BufferSettings::default()
137
0
    }
138
}
139
140
/// Decodes gRPC message types
141
pub trait Decoder {
142
    /// The type that is decoded.
143
    type Item;
144
145
    /// The type of unrecoverable frame decoding errors.
146
    type Error: From<io::Error>;
147
148
    /// Decode a message from the buffer.
149
    ///
150
    /// The buffer will contain exactly the bytes of a full message. There
151
    /// is no need to get the length from the bytes, gRPC framing is handled
152
    /// for you.
153
    fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error>;
154
155
    /// Controls how tonic creates and expands decode buffers.
156
0
    fn buffer_settings(&self) -> BufferSettings {
157
0
        BufferSettings::default()
158
0
    }
159
}