Skip to content

Commit 8986057

Browse files
authored
Merge pull request #1398 from wprzytula/scylla-cql-more-docs
scylla-cql: Write missing docstrings - part 1
2 parents 668f4e1 + 941c4b0 commit 8986057

32 files changed

+800
-33
lines changed

scylla-cql/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "scylla-cql"
33
version = "1.3.0"
44
edition = "2021"
55
rust-version = "1.70"
6-
description = "CQL data types and primitives, for interacting with Scylla."
6+
description = "CQL data types and primitives, for interacting with ScyllaDB."
77
repository = "https://github.com/scylladb/scylla-rust-driver"
88
readme = "../README.md"
99
keywords = ["database", "scylla", "cql", "cassandra"]

scylla-cql/src/deserialize/frame_slice.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
//! Defines `FrameSlice`, a borrowed reference to a part of the frame.
2+
13
use bytes::Bytes;
24

35
use crate::frame::frame_errors::LowLevelDeserializationError;
46
use crate::frame::types;
57

6-
/// A reference to a part of the frame.
8+
/// A borrowed reference to a part of the frame.
79
//
810
// # Design justification
911
//

scylla-cql/src/deserialize/result.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
//! Provides types for dealing with query result deserialization.
2+
//!
3+
//! Those yield raw rows, whose deserialization is handled by
4+
//! the `row` module.
5+
16
use bytes::Bytes;
27

38
use crate::frame::response::result::{
@@ -209,6 +214,9 @@ impl RawRowLendingIterator {
209214
Some(Ok(iter))
210215
}
211216

217+
/// Returns the bounds on the remaining length of the iterator.
218+
///
219+
/// This is analogous to [Iterator::size_hint].
212220
#[inline]
213221
pub fn size_hint(&self) -> (usize, Option<usize>) {
214222
// next() is written in a way that it does not progress on error, so once an error

scylla-cql/src/deserialize/row.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//! Provides types for dealing with row deserialization.
2+
//!
3+
//! Those yield raw values, whose deserialization is handled by
4+
//! the `value` module.
25
36
use std::fmt::Display;
47

@@ -12,8 +15,14 @@ use crate::value::{CqlValue, Row};
1215
/// Represents a raw, unparsed column value.
1316
#[non_exhaustive]
1417
pub struct RawColumn<'frame, 'metadata> {
18+
/// Index of the column in the row.
1519
pub index: usize,
20+
21+
/// Specification of the column, including its name and type.
1622
pub spec: &'metadata ColumnSpec<'metadata>,
23+
24+
/// Slice of the frame that contains the serialized value of the column.
25+
/// None means that the column is null.
1726
pub slice: Option<FrameSlice<'frame>>,
1827
}
1928

scylla-cql/src/deserialize/value.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,7 @@ impl<'frame, 'metadata> UdtIterator<'frame, 'metadata> {
14511451
}
14521452
}
14531453

1454+
/// Returns remaining (i.e., not yet deserialized) fields of the UDT.
14541455
#[inline]
14551456
pub fn fields(&self) -> &'metadata [(Cow<'metadata, str>, ColumnType<'metadata>)] {
14561457
self.remaining_fields

scylla-cql/src/frame/frame_errors.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Low-level errors that can occur during CQL frame parsing and serialization.
2+
13
use std::error::Error;
24
use std::sync::Arc;
35

@@ -67,6 +69,8 @@ pub enum FrameHeaderParseError {
6769
#[error("Received frame marked as coming from a client")]
6870
FrameFromClient,
6971

72+
/// Received a frame marked as coming from a server, while expecting a frame
73+
/// coming from a client.
7074
// FIXME: this should not belong here. User always expects a frame from server.
7175
// This variant is only used in scylla-proxy - need to investigate it later.
7276
#[error("Received frame marked as coming from the server")]
@@ -151,6 +155,7 @@ pub enum CqlResponseParseError {
151155
}
152156

153157
impl CqlResponseParseError {
158+
/// Retrieves the kind of CQL response that this error corresponds to.
154159
pub fn to_response_kind(&self) -> CqlResponseKind {
155160
match self {
156161
CqlResponseParseError::CqlErrorParseError(_) => CqlResponseKind::Error,

scylla-cql/src/frame/mod.rs

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
//! Abstractions of the CQL wire protocol:
2+
//! - request and response frames' representation and ser/de;
3+
//! - frame header and body;
4+
//! - serialization and deserialization of low-level CQL protocol types;
5+
//! - protocol features negotiation;
6+
//! - compression, tracing, custom payload support;
7+
//! - consistency levels;
8+
//! - errors that can occur during the above operations.
9+
//!
10+
111
pub mod frame_errors;
212
pub mod protocol_features;
313
pub mod request;
@@ -25,13 +35,21 @@ const HEADER_SIZE: usize = 9;
2535

2636
pub mod flag {
2737
//! Frame flags
38+
39+
/// The frame contains a compressed body.
2840
pub const COMPRESSION: u8 = 0x01;
41+
42+
/// The frame contains tracing ID.
2943
pub const TRACING: u8 = 0x02;
44+
45+
/// The frame contains a custom payload.
3046
pub const CUSTOM_PAYLOAD: u8 = 0x04;
47+
48+
/// The frame contains warnings.
3149
pub const WARNING: u8 = 0x08;
3250
}
3351

34-
/// All of the Authenticators supported by Scylla
52+
/// All of the Authenticators supported by ScyllaDB
3553
#[derive(Debug, PartialEq, Eq, Clone)]
3654
// Check triggers because all variants end with "Authenticator".
3755
// TODO(2.0): Remove the "Authenticator" postfix from variants.
@@ -54,6 +72,7 @@ pub enum Compression {
5472
}
5573

5674
impl Compression {
75+
/// Returns the string representation of the compression algorithm.
5776
pub fn as_str(&self) -> &'static str {
5877
match self {
5978
Compression::Lz4 => "lz4",
@@ -89,11 +108,21 @@ impl Display for Compression {
89108
}
90109
}
91110

111+
/// A serialized CQL request frame, nearly ready to be sent over the wire.
112+
///
113+
/// The only difference from a real frame is that it does not contain the stream number yet.
114+
/// The stream number is set by the `set_stream` method before sending.
92115
pub struct SerializedRequest {
93116
data: Vec<u8>,
94117
}
95118

96119
impl SerializedRequest {
120+
/// Creates a new serialized request frame from a request object.
121+
///
122+
/// # Parameters
123+
/// - `req`: The request object to serialize. Must implement `SerializableRequest`.
124+
/// - `compression`: An optional compression algorithm to use for the request body.
125+
/// - `tracing`: A boolean indicating whether to request tracing information in the response.
97126
pub fn make<R: SerializableRequest>(
98127
req: &R,
99128
compression: Option<Compression>,
@@ -125,20 +154,32 @@ impl SerializedRequest {
125154
Ok(Self { data })
126155
}
127156

157+
/// Sets the stream number for this request frame.
158+
/// Intended to be called before sending the request,
159+
/// once a stream ID has been assigned.
128160
pub fn set_stream(&mut self, stream: i16) {
129161
self.data[2..4].copy_from_slice(&stream.to_be_bytes());
130162
}
131163

164+
/// Returns the serialized frame data, including the header and body.
132165
pub fn get_data(&self) -> &[u8] {
133166
&self.data[..]
134167
}
135168
}
136169

137-
// Parts of the frame header which are not determined by the request/response type.
170+
/// Parts of the frame header which are not determined by the request/response type.
138171
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
139172
pub struct FrameParams {
173+
/// The version of the frame protocol. Currently, only version 4 is supported.
174+
/// The most significant bit (0x80) is treated specially:
175+
/// it indicates whether the frame is from the client or server.
140176
pub version: u8,
177+
178+
/// Flags for the frame, indicating features like compression, tracing, etc.
141179
pub flags: u8,
180+
181+
/// The stream ID for this frame, which allows matching requests and responses
182+
/// in a multiplexed connection.
142183
pub stream: i16,
143184
}
144185

@@ -152,6 +193,8 @@ impl Default for FrameParams {
152193
}
153194
}
154195

196+
/// Reads a response frame from the provided reader (usually, a socket).
197+
/// Then parses and validates the frame header and extracts the body.
155198
pub async fn read_response_frame(
156199
reader: &mut (impl AsyncRead + Unpin),
157200
) -> Result<(FrameParams, ResponseOpcode, Bytes), FrameHeaderParseError> {
@@ -203,13 +246,29 @@ pub async fn read_response_frame(
203246
Ok((frame_params, opcode, raw_body.into_inner().into()))
204247
}
205248

249+
/// Represents the already parsed response body extensions,
250+
/// including trace ID, warnings, and custom payload,
251+
/// and the remaining body raw data.
206252
pub struct ResponseBodyWithExtensions {
253+
/// The trace ID if tracing was requested in the request.
254+
///
255+
/// This can be used to issue a follow-up request to the server
256+
/// to get detailed tracing information about the request.
207257
pub trace_id: Option<Uuid>,
258+
259+
/// Warnings returned by the server, if any.
208260
pub warnings: Vec<String>,
209-
pub body: Bytes,
261+
262+
/// Custom payload (see [the CQL protocol description of the feature](https://github.com/apache/cassandra/blob/a39f3b066f010d465a1be1038d5e06f1e31b0391/doc/native_protocol_v4.spec#L276))
263+
/// returned by the server, if any.
210264
pub custom_payload: Option<HashMap<String, Bytes>>,
265+
266+
/// The remaining body data after parsing the extensions.
267+
pub body: Bytes,
211268
}
212269

270+
/// Decompresses the response body if compression is enabled,
271+
/// and parses any extensions like trace ID, warnings, and custom payload.
213272
pub fn parse_response_body_extensions(
214273
flags: u8,
215274
compression: Option<Compression>,
@@ -260,11 +319,13 @@ pub fn parse_response_body_extensions(
260319
Ok(ResponseBodyWithExtensions {
261320
trace_id,
262321
warnings,
263-
body,
264322
custom_payload,
323+
body,
265324
})
266325
}
267326

327+
/// Compresses the request body using the specified compression algorithm,
328+
/// appending the compressed data to the provided output buffer.
268329
pub fn compress_append(
269330
uncomp_body: &[u8],
270331
compression: Compression,
@@ -291,6 +352,8 @@ pub fn compress_append(
291352
}
292353
}
293354

355+
/// Deompresses the response body using the specified compression algorithm
356+
/// and returns the decompressed data as an owned buffer.
294357
pub fn decompress(
295358
mut comp_body: &[u8],
296359
compression: Compression,

scylla-cql/src/frame/protocol_features.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,56 @@
1+
//! Implementation and negotiation of extensions to the CQL protocol.
2+
13
use std::borrow::Cow;
24
use std::collections::HashMap;
35

46
const RATE_LIMIT_ERROR_EXTENSION: &str = "SCYLLA_RATE_LIMIT_ERROR";
7+
/// The extension used to add metadata for LWT optimization.
8+
/// See [ProtocolFeatures::lwt_optimization_meta_bit_mask] and
9+
/// [related issue](https://github.com/scylladb/scylla-rust-driver/issues/100)
10+
/// for more details.
511
pub const SCYLLA_LWT_ADD_METADATA_MARK_EXTENSION: &str = "SCYLLA_LWT_ADD_METADATA_MARK";
12+
/// The key of the single entry of the LWT optimization extension,
13+
/// which entry is a bit mask for the frame flags used to mark LWT frames.
614
pub const LWT_OPTIMIZATION_META_BIT_MASK_KEY: &str = "LWT_OPTIMIZATION_META_BIT_MASK";
715
const TABLETS_ROUTING_V1_KEY: &str = "TABLETS_ROUTING_V1";
816

17+
/// Which protocol extensions are supported by the server.
18+
///
19+
/// This is used to inform the server about the features that the client supports,
20+
/// so that the server can adjust its behavior accordingly.
21+
///
22+
/// So to draw the picture:
23+
/// - server responds to an `OPTIONS` frame with a `SUPPORTED` frame with the list of
24+
/// protocol features it supports;
25+
/// - client parses the `SUPPORTED` frame by extracting extensions it recognizes (supports)
26+
/// and creates a `ProtocolFeatures` instance;
27+
/// - from now on, client uses this instance to determine how to handle certain frames,
28+
/// e.g. whether to expect a rate limit error or how to handle LWT operations;
29+
/// - client also adds the features it supports to the `STARTUP` frame and sends it to
30+
/// the server, which finishes the extensions negotiation process.
931
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
1032
#[non_exhaustive]
1133
pub struct ProtocolFeatures {
34+
/// The error code to use for rate limit errors, if negotiated.
1235
pub rate_limit_error: Option<i32>,
36+
37+
/// The bit mask used for the LWT optimization, if negotiated.
38+
/// This is used to mark PREPARED response frames as related to LWT operations
39+
/// in order to to optimize the handling of LWT requests.
40+
///
41+
/// The mask is ANDed with the flags of the PREPARED response frame,
42+
/// and if the result is equal to the mask, it means that the frame is related
43+
/// to an LWT operation.
1344
pub lwt_optimization_meta_bit_mask: Option<u32>,
45+
46+
/// Whether the server supports tablets routing v1.
1447
pub tablets_v1_supported: bool,
1548
}
1649

1750
// TODO: Log information about options which failed to parse
1851

1952
impl ProtocolFeatures {
53+
/// Parses the supported protocol features from the `supported` map.
2054
pub fn parse_from_supported(supported: &HashMap<String, Vec<String>>) -> Self {
2155
Self {
2256
rate_limit_error: Self::maybe_parse_rate_limit_error(supported),
@@ -52,6 +86,7 @@ impl ProtocolFeatures {
5286
.find_map(|v| v.as_str().strip_prefix(key)?.strip_prefix('='))
5387
}
5488

89+
/// Adds the protocol features as STARTUP options.
5590
pub fn add_startup_options(&self, options: &mut HashMap<Cow<'_, str>, Cow<'_, str>>) {
5691
if self.rate_limit_error.is_some() {
5792
options.insert(Cow::Borrowed(RATE_LIMIT_ERROR_EXTENSION), Cow::Borrowed(""));
@@ -68,6 +103,9 @@ impl ProtocolFeatures {
68103
}
69104
}
70105

106+
/// Checks if the given flags of a PREPARED response contain the LWT optimization mark.
107+
///
108+
/// If the extension was not negotiated, it conservatively returns `false`.
71109
pub fn prepared_flags_contain_lwt_mark(&self, flags: u32) -> bool {
72110
self.lwt_optimization_meta_bit_mask
73111
.map(|mask| (flags & mask) == mask)

scylla-cql/src/frame/request/auth_response.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! CQL protocol-level representation of a `AUTH_RESPONSE` request.
2+
13
use std::num::TryFromIntError;
24

35
use thiserror::Error;
@@ -7,8 +9,11 @@ use crate::frame::frame_errors::CqlRequestSerializationError;
79
use crate::frame::request::{RequestOpcode, SerializableRequest};
810
use crate::frame::types::write_bytes_opt;
911

10-
// Implements Authenticate Response
12+
/// Represents AUTH_RESPONSE CQL request.
13+
///
14+
/// This request is sent by the client to respond to an authentication challenge.
1115
pub struct AuthResponse {
16+
/// Raw response bytes.
1217
pub response: Option<Vec<u8>>,
1318
}
1419

0 commit comments

Comments
 (0)