scylla_cql/frame/request/
startup.rs

1//! CQL protocol-level representation of a `STARTUP` request.
2
3use thiserror::Error;
4
5use crate::frame::frame_errors::CqlRequestSerializationError;
6
7use std::{borrow::Cow, collections::HashMap, num::TryFromIntError};
8
9use crate::{
10    frame::request::{RequestOpcode, SerializableRequest},
11    frame::types,
12};
13
14use super::DeserializableRequest;
15
16/// The CQL protocol-level representation of an `STARTUP` request,
17/// used to finalise connection negotiation phase and establish the CQL connection.
18pub struct Startup<'a> {
19    /// The protocol options that were suggested by the server and accepted by the client.
20    pub options: HashMap<Cow<'a, str>, Cow<'a, str>>,
21}
22
23impl SerializableRequest for Startup<'_> {
24    const OPCODE: RequestOpcode = RequestOpcode::Startup;
25
26    fn serialize(&self, buf: &mut Vec<u8>) -> Result<(), CqlRequestSerializationError> {
27        types::write_string_map(&self.options, buf)
28            .map_err(StartupSerializationError::OptionsSerialization)?;
29        Ok(())
30    }
31}
32
33/// An error type returned when serialization of STARTUP request fails.
34#[non_exhaustive]
35#[derive(Error, Debug, Clone)]
36pub enum StartupSerializationError {
37    /// Failed to serialize startup options.
38    #[error("Malformed startup options: {0}")]
39    OptionsSerialization(TryFromIntError),
40}
41
42impl DeserializableRequest for Startup<'_> {
43    fn deserialize(buf: &mut &[u8]) -> Result<Self, super::RequestDeserializationError> {
44        // Note: this is inefficient, but it's only used for tests and it's not common
45        // to deserialize STARTUP frames anyway.
46        let options = types::read_string_map(buf)?
47            .into_iter()
48            .map(|(k, v)| (k.into(), v.into()))
49            .collect();
50        Ok(Self { options })
51    }
52}