cloud_api_types: Add types for WebSocket protocol (#35753)

Marshall Bowers created

This PR adds types for the Cloud WebSocket protocol to the
`cloud_api_types` crate.

Release Notes:

- N/A

Change summary

Cargo.lock                                       |  2 +
Cargo.toml                                       |  1 
crates/cloud_api_types/Cargo.toml                |  2 +
crates/cloud_api_types/src/cloud_api_types.rs    |  1 
crates/cloud_api_types/src/websocket_protocol.rs | 28 ++++++++++++++++++
5 files changed, 34 insertions(+)

Detailed changes

Cargo.lock 🔗

@@ -3081,7 +3081,9 @@ dependencies = [
 name = "cloud_api_types"
 version = "0.1.0"
 dependencies = [
+ "anyhow",
  "chrono",
+ "ciborium",
  "cloud_llm_client",
  "pretty_assertions",
  "serde",

Cargo.toml 🔗

@@ -461,6 +461,7 @@ bytes = "1.0"
 cargo_metadata = "0.19"
 cargo_toml = "0.21"
 chrono = { version = "0.4", features = ["serde"] }
+ciborium = "0.2"
 circular-buffer = "1.0"
 clap = { version = "4.4", features = ["derive"] }
 cocoa = "0.26"

crates/cloud_api_types/Cargo.toml 🔗

@@ -12,7 +12,9 @@ workspace = true
 path = "src/cloud_api_types.rs"
 
 [dependencies]
+anyhow.workspace = true
 chrono.workspace = true
+ciborium.workspace = true
 cloud_llm_client.workspace = true
 serde.workspace = true
 workspace-hack.workspace = true

crates/cloud_api_types/src/websocket_protocol.rs 🔗

@@ -0,0 +1,28 @@
+use anyhow::{Context as _, Result};
+use serde::{Deserialize, Serialize};
+
+/// The version of the Cloud WebSocket protocol.
+pub const PROTOCOL_VERSION: u32 = 0;
+
+/// The name of the header used to indicate the protocol version in use.
+pub const PROTOCOL_VERSION_HEADER_NAME: &str = "x-zed-protocol-version";
+
+/// A message from Cloud to the Zed client.
+#[derive(Serialize, Deserialize)]
+pub enum MessageToClient {
+    /// The user was updated and should be refreshed.
+    UserUpdated,
+}
+
+impl MessageToClient {
+    pub fn serialize(&self) -> Result<Vec<u8>> {
+        let mut buffer = Vec::new();
+        ciborium::into_writer(self, &mut buffer).context("failed to serialize message")?;
+
+        Ok(buffer)
+    }
+
+    pub fn deserialize(data: &[u8]) -> Result<Self> {
+        ciborium::from_reader(data).context("failed to deserialize message")
+    }
+}