From df0417581777cda73d100c49f71b9231663fcbbc Mon Sep 17 00:00:00 2001 From: MasterPtato Date: Thu, 7 May 2026 17:24:45 -0700 Subject: [PATCH] feat(vbare): add conversion boilerplate generator, fix envoy protocol conversion --- .claude/reference/vbare-migrations.md | 95 + .../sdks/rust/envoy-protocol/src/versioned.rs | 1846 ----------------- .../rust/envoy-protocol/src/versioned/mod.rs | 895 ++++++++ .../envoy-protocol/src/versioned/v1_to_v2.rs | 740 +++++++ .../envoy-protocol/src/versioned/v2_to_v1.rs | 763 +++++++ .../envoy-protocol/src/versioned/v2_to_v3.rs | 881 ++++++++ .../envoy-protocol/src/versioned/v3_to_v2.rs | 873 ++++++++ .../envoy-protocol/src/versioned/v3_to_v4.rs | 878 ++++++++ .../envoy-protocol/src/versioned/v4_to_v3.rs | 898 ++++++++ .../envoy-protocol/src/versioned/v4_to_v5.rs | 1100 ++++++++++ .../envoy-protocol/src/versioned/v5_to_v4.rs | 1093 ++++++++++ .../src/versioned_conversions.in | 532 ----- .../envoy-protocol/tests/remote_sql_compat.rs | 7 +- package.json | 3 +- pnpm-lock.yaml | 107 +- scripts/vbare-gen-converters/index.ts | 560 +++++ .../vbare-gen-converters/templates/enum.hbs | 7 + .../vbare-gen-converters/templates/file.hbs | 14 + .../vbare-gen-converters/templates/struct.hbs | 7 + .../vbare-gen-converters/templates/todo.hbs | 4 + .../vbare-gen-converters/templates/union.hbs | 7 + .../templates/wrapper-alias.hbs | 3 + 22 files changed, 8898 insertions(+), 2415 deletions(-) create mode 100644 .claude/reference/vbare-migrations.md delete mode 100644 engine/sdks/rust/envoy-protocol/src/versioned.rs create mode 100644 engine/sdks/rust/envoy-protocol/src/versioned/mod.rs create mode 100644 engine/sdks/rust/envoy-protocol/src/versioned/v1_to_v2.rs create mode 100644 engine/sdks/rust/envoy-protocol/src/versioned/v2_to_v1.rs create mode 100644 engine/sdks/rust/envoy-protocol/src/versioned/v2_to_v3.rs create mode 100644 engine/sdks/rust/envoy-protocol/src/versioned/v3_to_v2.rs create mode 100644 engine/sdks/rust/envoy-protocol/src/versioned/v3_to_v4.rs create mode 100644 engine/sdks/rust/envoy-protocol/src/versioned/v4_to_v3.rs create mode 100644 engine/sdks/rust/envoy-protocol/src/versioned/v4_to_v5.rs create mode 100644 engine/sdks/rust/envoy-protocol/src/versioned/v5_to_v4.rs delete mode 100644 engine/sdks/rust/envoy-protocol/src/versioned_conversions.in create mode 100644 scripts/vbare-gen-converters/index.ts create mode 100644 scripts/vbare-gen-converters/templates/enum.hbs create mode 100644 scripts/vbare-gen-converters/templates/file.hbs create mode 100644 scripts/vbare-gen-converters/templates/struct.hbs create mode 100644 scripts/vbare-gen-converters/templates/todo.hbs create mode 100644 scripts/vbare-gen-converters/templates/union.hbs create mode 100644 scripts/vbare-gen-converters/templates/wrapper-alias.hbs diff --git a/.claude/reference/vbare-migrations.md b/.claude/reference/vbare-migrations.md new file mode 100644 index 0000000000..97c46172ac --- /dev/null +++ b/.claude/reference/vbare-migrations.md @@ -0,0 +1,95 @@ +# VBARE schema migrations + +Procedural guide for adding a new schema version to a vbare-backed protocol crate (envoy-protocol, runner-protocol, epoxy-protocol, depot-protocol, ups-protocol). + +## Layout + +Every protocol crate has: + +- `engine/sdks/schemas//v{N}.bare` — versioned schema files. **Never edit a published one in place.** +- `engine/sdks/rust//src/generated.rs` — `include!`s vbare-generated `vN_generated.rs` into `pub mod vN`. +- `engine/sdks/rust//src/versioned/` — directory with one `mod.rs` and one `vN_to_vM.rs` file per adjacent migration step. +- `engine/sdks/rust//src/lib.rs` — re-exports `generated::v{LATEST}::*` and `PROTOCOL_VERSION`. + +`mod.rs` owns the multi-variant wrapper enums and `OwnedVersionedData` impls. The `vN_to_vM.rs` files own the field-by-field per-type converters. + +## Adding a new schema version + +1. **Copy the latest schema** to a new file: `cp engine/sdks/schemas//vN.bare engine/sdks/schemas//v{N+1}.bare`. Edit the new file. +2. **Bump the protocol constant** alongside the schema. For most crates that's `PROTOCOL_VERSION` (or `PROTOCOL_MK2_VERSION` for runner-protocol). For runner-protocol also bump `rivetkit-typescript/packages/engine-runner/src/mod.ts` `PROTOCOL_VERSION`. +3. **Update `lib.rs`** to re-export the new `generated::v{N+1}::*`. +4. **Run the converter scaffolder** for the new pair: + ``` + tsx scripts/vbare-gen-converters/index.ts \ + engine/sdks/schemas//vN.bare \ + engine/sdks/schemas//v{N+1}.bare \ + engine/sdks/rust//src/versioned \ + --types Root1,Root2,... + ``` + `--types` is a comma-separated list of the wrapper-enum names (e.g. `ToEnvoy,ToRivet,ToEnvoyConn,ToGateway,ToOutbound,ActorCommandKeyData` for envoy-protocol). The script transitively pulls in every type those wrappers reference; types that are byte-identical primitive aliases are skipped (no converter needed). + This writes two files: `vN_to_v{N+1}.rs` and `v{N+1}_to_vN.rs`. +5. **Fill in every `todo!()`.** The script puts a `todo!()` wherever a struct field, union variant, or enum value exists on one side but not the other. For each one, decide: + - **Field added** (forward direction): default value, e.g. `None` for optional, the moral equivalent for non-optional. + - **Field dropped** (backward direction): nothing to fill — the field doesn't appear in the target struct. + - **Variant added**: forward direction unreachable from older payloads. Backward direction must `bail!(...)` with a descriptive message, or — if the feature is part of a tracked compatibility surface — return a structured error like `incompatible(ProtocolCompatibilityFeature::Foo, ...)`. + - **Variant whose shape changed too much to map cleanly**: bail at the union arm with a `bail!(...)` describing the incompatibility. Inner per-type converters for that variant become unreachable; their auto-generated `todo!()`s in field positions are dead and can stay. +6. **Update `mod.rs`**: + - Add a `Vn` variant to each wrapper enum. + - Add a `mod vN_to_v{N+1};` and `mod v{N+1}_to_vN;` declaration. + - Add the new version to every match arm in `deserialize_version` and `serialize_version`. + - Update `type Latest = vN::T;`, `wrap_latest`, and `unwrap_latest` to point at the new latest. + - Append the new step methods (`vN_to_v{N+1}`, `v{N+1}_to_vN`) to the `impl T` block. + - Update `deserialize_converters` and `serialize_converters`. +7. **Run the crate's tests**: `cargo test -p `. Add a round-trip test that exercises the new step (round-trip from latest down to vN-1 and back). + +## Converter chain ordering (mod.rs) + +The two converter vectors look identical-shaped but walk in **opposite directions**, and getting them backwards silently breaks `serialize`: + +- `deserialize_converters` is **bottom-up**: index `i` upgrades V{i+1} to V{i+2}. For five versions: `[v1_to_v2, v2_to_v3, v3_to_v4, v4_to_v5]`. +- `serialize_converters` is **top-down**: index `0` downgrades the latest variant one step. For five versions: `[v5_to_v4, v4_to_v3, v3_to_v2, v2_to_v1]`. + +The vbare runtime takes a prefix of `serialize_converters` based on the requested target version (`take((latest + 1) - target)`), so a reversed list will run downgrade steps in the wrong order and either panic on `Self::Vn(_) => bail!("unexpected version")` or produce a wrongly-typed wire payload. + +## Why each converter is `Result` + +Every generated converter returns `Result` even when the body is infallible (`Ok(...)` of a field-by-field copy). Reasons: + +- Cross-version migrations frequently need to `bail!` at union arms when downgrading. Forcing every converter to be `Result` means a downgrade can drop in a `bail!` without changing the function signature or rippling `?`s through every caller. +- Iteration patterns (`.collect::>>()?`, `.transpose()?`) compose uniformly when every leaf is fallible. Mixed fallible/infallible signatures fight type inference inside closures. +- The compiler optimises `Ok(x)?` away. There is no runtime cost. + +## Avoid + +- **Editing a published `*.bare`** in place. Always add a new versioned file. +- **`serde_bare::to_vec` + `from_slice`** to "convert" between adjacent versions. Even if the bytes are identical today, schema drift breaks it silently. Always reconstruct field-by-field. The script enforces this by emitting field assignments rather than a re-serialize round-trip. +- **`vec![Ok, Ok, ...]` converter chains**. If the wrapper enum has multiple version variants but the converters are no-ops, the chain isn't actually walking — `unwrap_latest()` will fail with "version not latest" because no upgrade ran. +- **Single-variant wrapper enums** (`enum ToEnvoy { V5(v5::ToEnvoy) }`). The whole point of `OwnedVersionedData` is that each version inhabits its own variant and the chain walks them. A single variant collapses the chain into manual nested calls inside `deserialize_version` / `serialize_version`, which is the exact anti-pattern this layout replaces. See `engine/sdks/rust/envoy-protocol/src/versioned/mod.rs` and `engine/sdks/rust/epoxy-protocol/src/versioned.rs` for correct shapes. + +## The converter script + +Lives at `scripts/vbare-gen-converters/`: + +- `index.ts` — entry point. Parses BARE via `@bare-ts/tools`, walks the type graph, emits Rust. +- `templates/*.hbs` — Handlebars templates for the per-type Rust output (`struct.hbs`, `union.hbs`, `enum.hbs`, `wrapper-alias.hbs`, `todo.hbs`, `file.hbs`). + +CLI: + +``` +tsx scripts/vbare-gen-converters/index.ts \ + [--types T1,T2,...] [--from-ns vN] [--to-ns vM] +``` + +What it does NOT generate: + +- **`mod.rs`** — the wrapper enums and `OwnedVersionedData` impls are hand-written (boilerplate that's small per crate and rarely touched once correct). +- **Protocol-specific compatibility errors** like `ProtocolCompatibilityError` in envoy-protocol's `mod.rs`. Add those by hand and reference them from the converter file's bail sites. + +What it does: + +- One `Result`-returning function per shared user-defined type, named `convert___to_`. +- Skips top-level converters for primitive aliases (`type Id str`) and `void` types — both are identity in Rust so a wrapping function would only add noise. +- Uses `todo!()` for any field, union variant, or enum value that isn't structurally identical on both sides. +- Inner expressions for nested aliases use `?` to propagate; `Option` uses `.map(...).transpose()?`; `Vec` uses `.collect::>>()?`; maps wrap their iter map closure with an explicit `-> Result<_>` return. + +Re-running the script overwrites the existing files. **Do not re-run the script after filling in todos** unless you are prepared to redo every manual edit. The intended flow is: scaffold once, fill in once, leave the file alone forever (per the vbare design tenet that migration code must never be retroactively changed). diff --git a/engine/sdks/rust/envoy-protocol/src/versioned.rs b/engine/sdks/rust/envoy-protocol/src/versioned.rs deleted file mode 100644 index 94965d2c07..0000000000 --- a/engine/sdks/rust/envoy-protocol/src/versioned.rs +++ /dev/null @@ -1,1846 +0,0 @@ -use anyhow::{Result, bail}; -use std::{error::Error, fmt}; -use vbare::OwnedVersionedData; - -use crate::generated::{v1, v2, v3, v4, v5}; - -fn convert_same_bytes(message: T) -> Result -where - T: serde::Serialize, - U: serde::de::DeserializeOwned, -{ - serde_bare::from_slice(&serde_bare::to_vec(&message)?).map_err(Into::into) -} - -fn convert_same_bytes_ref(message: &T) -> Result -where - T: serde::Serialize + ?Sized, - U: serde::de::DeserializeOwned, -{ - serde_bare::from_slice(&serde_bare::to_vec(message)?).map_err(Into::into) -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ProtocolCompatibilityFeature { - SqliteStartupData, - SqlitePageIo, - SqlitePageRange, - RemoteSqliteExecution, -} - -impl ProtocolCompatibilityFeature { - fn description(self, direction: ProtocolCompatibilityDirection) -> &'static str { - match self { - ProtocolCompatibilityFeature::SqliteStartupData => "sqlite startup data", - ProtocolCompatibilityFeature::SqlitePageIo => match direction { - ProtocolCompatibilityDirection::ToEnvoy => "sqlite responses", - ProtocolCompatibilityDirection::ToRivet => "sqlite requests", - }, - ProtocolCompatibilityFeature::SqlitePageRange => match direction { - ProtocolCompatibilityDirection::ToEnvoy => "sqlite range responses", - ProtocolCompatibilityDirection::ToRivet => "sqlite range requests", - }, - ProtocolCompatibilityFeature::RemoteSqliteExecution => match direction { - ProtocolCompatibilityDirection::ToEnvoy => "remote sqlite responses", - ProtocolCompatibilityDirection::ToRivet => "remote sqlite requests", - }, - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ProtocolCompatibilityDirection { - ToEnvoy, - ToRivet, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct ProtocolCompatibilityError { - pub feature: ProtocolCompatibilityFeature, - pub direction: ProtocolCompatibilityDirection, - pub required_version: u16, - pub target_version: u16, -} - -impl fmt::Display for ProtocolCompatibilityError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let verb = match self.feature { - ProtocolCompatibilityFeature::SqliteStartupData => "requires", - ProtocolCompatibilityFeature::SqlitePageIo - | ProtocolCompatibilityFeature::SqlitePageRange - | ProtocolCompatibilityFeature::RemoteSqliteExecution => "require", - }; - - write!( - f, - "{} {} envoy-protocol v{} but target version is v{}", - self.feature.description(self.direction), - verb, - self.required_version, - self.target_version - ) - } -} - -impl Error for ProtocolCompatibilityError {} - -fn incompatible( - feature: ProtocolCompatibilityFeature, - direction: ProtocolCompatibilityDirection, - required_version: u16, - target_version: u16, -) -> anyhow::Error { - ProtocolCompatibilityError { - feature, - direction, - required_version, - target_version, - } - .into() -} - -pub enum ToEnvoy { - V5(v5::ToEnvoy), -} - -impl OwnedVersionedData for ToEnvoy { - type Latest = v5::ToEnvoy; - - fn wrap_latest(latest: Self::Latest) -> Self { - Self::V5(latest) - } - - fn unwrap_latest(self) -> Result { - match self { - Self::V5(data) => Ok(data), - } - } - - fn deserialize_version(payload: &[u8], version: u16) -> Result { - Ok(Self::V5(match version { - 1 => convert_to_envoy_v4_to_v5(convert_to_envoy_v3_to_v4(convert_to_envoy_v2_to_v3( - convert_to_envoy_v1_to_v2(serde_bare::from_slice(payload)?)?, - )?)?)?, - 2 => convert_to_envoy_v4_to_v5(convert_to_envoy_v3_to_v4(convert_to_envoy_v2_to_v3( - serde_bare::from_slice(payload)?, - )?)?)?, - 3 => convert_to_envoy_v4_to_v5(convert_to_envoy_v3_to_v4(serde_bare::from_slice( - payload, - )?)?)?, - 4 => convert_to_envoy_v4_to_v5(serde_bare::from_slice(payload)?)?, - 5 => serde_bare::from_slice(payload)?, - _ => bail!("invalid version: {version}"), - })) - } - - fn serialize_version(self, version: u16) -> Result> { - let Self::V5(data) = self; - match version { - 1 => { - let data = convert_to_envoy_v5_to_v4(data)?; - serde_bare::to_vec(&convert_to_envoy_v2_to_v1(convert_to_envoy_v3_to_v2( - convert_to_envoy_v4_to_v3(data, 1)?, - )?)?) - .map_err(Into::into) - } - 2 => { - let data = convert_to_envoy_v5_to_v4(data)?; - serde_bare::to_vec(&convert_to_envoy_v3_to_v2(convert_to_envoy_v4_to_v3( - data, 2, - )?)?) - .map_err(Into::into) - } - 3 => { - let data = convert_to_envoy_v5_to_v4(data)?; - serde_bare::to_vec(&convert_to_envoy_v4_to_v3(data, 3)?).map_err(Into::into) - } - 4 => serde_bare::to_vec(&convert_to_envoy_v5_to_v4(data)?).map_err(Into::into), - 5 => serde_bare::to_vec(&data).map_err(Into::into), - _ => bail!("invalid version: {version}"), - } - } - - fn deserialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } - - fn serialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } -} - -pub enum ToRivet { - V5(v5::ToRivet), -} - -impl OwnedVersionedData for ToRivet { - type Latest = v5::ToRivet; - - fn wrap_latest(latest: Self::Latest) -> Self { - Self::V5(latest) - } - - fn unwrap_latest(self) -> Result { - match self { - Self::V5(data) => Ok(data), - } - } - - fn deserialize_version(payload: &[u8], version: u16) -> Result { - Ok(Self::V5(match version { - 1 | 2 => convert_to_rivet_v4_to_v5(convert_to_rivet_v3_to_v4( - convert_to_rivet_v2_to_v3(serde_bare::from_slice(payload)?)?, - )?)?, - 3 => convert_to_rivet_v4_to_v5(convert_to_rivet_v3_to_v4(serde_bare::from_slice( - payload, - )?)?)?, - 4 => convert_to_rivet_v4_to_v5(serde_bare::from_slice(payload)?)?, - 5 => serde_bare::from_slice(payload)?, - _ => bail!("invalid version: {version}"), - })) - } - - fn serialize_version(self, version: u16) -> Result> { - let Self::V5(data) = self; - match version { - 1 | 2 => { - let data = convert_to_rivet_v5_to_v4(data)?; - serde_bare::to_vec(&convert_to_rivet_v3_to_v2(convert_to_rivet_v4_to_v3( - data, version, - )?)?) - .map_err(Into::into) - } - 3 => { - let data = convert_to_rivet_v5_to_v4(data)?; - serde_bare::to_vec(&convert_to_rivet_v4_to_v3(data, 3)?).map_err(Into::into) - } - 4 => serde_bare::to_vec(&convert_to_rivet_v5_to_v4(data)?).map_err(Into::into), - 5 => serde_bare::to_vec(&data).map_err(Into::into), - _ => bail!("invalid version: {version}"), - } - } - - fn deserialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } - - fn serialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } -} - -pub enum ToEnvoyConn { - V5(v5::ToEnvoyConn), -} - -impl OwnedVersionedData for ToEnvoyConn { - type Latest = v5::ToEnvoyConn; - - fn wrap_latest(latest: Self::Latest) -> Self { - Self::V5(latest) - } - - fn unwrap_latest(self) -> Result { - match self { - Self::V5(data) => Ok(data), - } - } - - fn deserialize_version(payload: &[u8], version: u16) -> Result { - Ok(Self::V5(match version { - 1 => convert_same_bytes(convert_to_envoy_conn_v1_to_v3(serde_bare::from_slice( - payload, - )?)?)?, - 2 => convert_same_bytes(convert_to_envoy_conn_v2_to_v3(serde_bare::from_slice( - payload, - )?)?)?, - 3 => convert_same_bytes(serde_bare::from_slice::(payload)?)?, - 4 => convert_same_bytes(serde_bare::from_slice::(payload)?)?, - 5 => serde_bare::from_slice(payload)?, - _ => bail!("invalid version: {version}"), - })) - } - - fn serialize_version(self, version: u16) -> Result> { - let Self::V5(data) = self; - let data_v4 = || convert_same_bytes_ref::<_, v4::ToEnvoyConn>(&data); - match version { - 1 => { - let data = data_v4()?; - let data_v3 = convert_same_bytes_ref::<_, v3::ToEnvoyConn>(&data)?; - serde_bare::to_vec(&convert_to_envoy_conn_v3_to_v1(data_v3)?).map_err(Into::into) - } - 2 => { - let data = data_v4()?; - let data_v3 = convert_same_bytes_ref::<_, v3::ToEnvoyConn>(&data)?; - serde_bare::to_vec(&convert_to_envoy_conn_v3_to_v2(data_v3)?).map_err(Into::into) - } - 3 => { - let data = data_v4()?; - serde_bare::to_vec(&convert_same_bytes_ref::<_, v3::ToEnvoyConn>(&data)?) - .map_err(Into::into) - } - 4 => serde_bare::to_vec(&data_v4()?).map_err(Into::into), - 5 => serde_bare::to_vec(&data).map_err(Into::into), - _ => bail!("invalid version: {version}"), - } - } - - fn deserialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } - - fn serialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } -} - -pub enum ToGateway { - V5(v5::ToGateway), -} - -impl OwnedVersionedData for ToGateway { - type Latest = v5::ToGateway; - - fn wrap_latest(latest: Self::Latest) -> Self { - Self::V5(latest) - } - - fn unwrap_latest(self) -> Result { - match self { - Self::V5(data) => Ok(data), - } - } - - fn deserialize_version(payload: &[u8], version: u16) -> Result { - Ok(Self::V5(match version { - 1 => convert_same_bytes(convert_to_gateway_v1_to_v3(serde_bare::from_slice( - payload, - )?))?, - 2 => convert_same_bytes(convert_to_gateway_v2_to_v3(serde_bare::from_slice( - payload, - )?))?, - 3 => convert_same_bytes(serde_bare::from_slice::(payload)?)?, - 4 => convert_same_bytes(serde_bare::from_slice::(payload)?)?, - 5 => serde_bare::from_slice(payload)?, - _ => bail!("invalid version: {version}"), - })) - } - - fn serialize_version(self, version: u16) -> Result> { - let Self::V5(data) = self; - let data_v4 = || convert_same_bytes_ref::<_, v4::ToGateway>(&data); - match version { - 1 => { - let data = data_v4()?; - let data = convert_same_bytes_ref::<_, v3::ToGateway>(&data)?; - serde_bare::to_vec(&convert_to_gateway_v3_to_v1(data)).map_err(Into::into) - } - 2 => { - let data = data_v4()?; - let data = convert_same_bytes_ref::<_, v3::ToGateway>(&data)?; - serde_bare::to_vec(&convert_to_gateway_v3_to_v2(data)).map_err(Into::into) - } - 3 => { - let data = data_v4()?; - serde_bare::to_vec(&convert_same_bytes_ref::<_, v3::ToGateway>(&data)?) - .map_err(Into::into) - } - 4 => serde_bare::to_vec(&data_v4()?).map_err(Into::into), - 5 => serde_bare::to_vec(&data).map_err(Into::into), - _ => bail!("invalid version: {version}"), - } - } - - fn deserialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } - - fn serialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } -} - -pub enum ToOutbound { - V5(v5::ToOutbound), -} - -impl OwnedVersionedData for ToOutbound { - type Latest = v5::ToOutbound; - - fn wrap_latest(latest: Self::Latest) -> Self { - Self::V5(latest) - } - - fn unwrap_latest(self) -> Result { - match self { - Self::V5(data) => Ok(data), - } - } - - fn deserialize_version(payload: &[u8], version: u16) -> Result { - Ok(Self::V5(match version { - 1 => convert_same_bytes(convert_to_outbound_v1_to_v3(serde_bare::from_slice( - payload, - )?))?, - 2 => convert_same_bytes(convert_to_outbound_v2_to_v3(serde_bare::from_slice( - payload, - )?))?, - 3 => convert_same_bytes(serde_bare::from_slice::(payload)?)?, - 4 => convert_same_bytes(serde_bare::from_slice::(payload)?)?, - 5 => serde_bare::from_slice(payload)?, - _ => bail!("invalid version: {version}"), - })) - } - - fn serialize_version(self, version: u16) -> Result> { - let Self::V5(data) = self; - let data_v4 = || convert_same_bytes_ref::<_, v4::ToOutbound>(&data); - match version { - 1 => { - let data = data_v4()?; - let data = convert_same_bytes_ref::<_, v3::ToOutbound>(&data)?; - serde_bare::to_vec(&convert_to_outbound_v3_to_v1(data)).map_err(Into::into) - } - 2 => { - let data = data_v4()?; - let data = convert_same_bytes_ref::<_, v3::ToOutbound>(&data)?; - serde_bare::to_vec(&convert_to_outbound_v3_to_v2(data)).map_err(Into::into) - } - 3 => { - let data = data_v4()?; - serde_bare::to_vec(&convert_same_bytes_ref::<_, v3::ToOutbound>(&data)?) - .map_err(Into::into) - } - 4 => serde_bare::to_vec(&data_v4()?).map_err(Into::into), - 5 => serde_bare::to_vec(&data).map_err(Into::into), - _ => bail!("invalid version: {version}"), - } - } - - fn deserialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } - - fn serialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } -} - -pub enum ActorCommandKeyData { - V5(v5::ActorCommandKeyData), -} - -impl OwnedVersionedData for ActorCommandKeyData { - type Latest = v5::ActorCommandKeyData; - - fn wrap_latest(latest: Self::Latest) -> Self { - Self::V5(latest) - } - - fn unwrap_latest(self) -> Result { - match self { - Self::V5(data) => Ok(data), - } - } - - fn deserialize_version(payload: &[u8], version: u16) -> Result { - Ok(Self::V5(match version { - 1 => convert_same_bytes(convert_actor_command_key_data_v1_to_v3( - serde_bare::from_slice(payload)?, - ))?, - 2 => convert_same_bytes(convert_actor_command_key_data_v2_to_v3( - serde_bare::from_slice(payload)?, - ))?, - 3 => convert_same_bytes(serde_bare::from_slice::(payload)?)?, - 4 => convert_same_bytes(serde_bare::from_slice::(payload)?)?, - 5 => serde_bare::from_slice(payload)?, - _ => bail!("invalid version: {version}"), - })) - } - - fn serialize_version(self, version: u16) -> Result> { - let Self::V5(data) = self; - let data_v4 = || convert_same_bytes_ref::<_, v4::ActorCommandKeyData>(&data); - match version { - 1 => { - let data = data_v4()?; - let data = convert_same_bytes_ref::<_, v3::ActorCommandKeyData>(&data)?; - serde_bare::to_vec(&convert_actor_command_key_data_v3_to_v1(data)) - .map_err(Into::into) - } - 2 => { - let data = data_v4()?; - let data = convert_same_bytes_ref::<_, v3::ActorCommandKeyData>(&data)?; - serde_bare::to_vec(&convert_actor_command_key_data_v3_to_v2(data)) - .map_err(Into::into) - } - 3 => { - let data = data_v4()?; - serde_bare::to_vec(&convert_same_bytes_ref::<_, v3::ActorCommandKeyData>( - &data, - )?) - .map_err(Into::into) - } - 4 => serde_bare::to_vec(&data_v4()?).map_err(Into::into), - 5 => serde_bare::to_vec(&data).map_err(Into::into), - _ => bail!("invalid version: {version}"), - } - } - - fn deserialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } - - fn serialize_converters() -> Vec Result> { - vec![Ok, Ok, Ok, Ok] - } -} - -fn convert_to_envoy_v4_to_v5(message: v4::ToEnvoy) -> Result { - Ok(match message { - v4::ToEnvoy::ToEnvoyInit(data) => v5::ToEnvoy::ToEnvoyInit(convert_same_bytes(data)?), - v4::ToEnvoy::ToEnvoyCommands(data) => { - v5::ToEnvoy::ToEnvoyCommands(convert_same_bytes(data)?) - } - v4::ToEnvoy::ToEnvoyAckEvents(data) => { - v5::ToEnvoy::ToEnvoyAckEvents(convert_same_bytes(data)?) - } - v4::ToEnvoy::ToEnvoyKvResponse(data) => { - v5::ToEnvoy::ToEnvoyKvResponse(convert_same_bytes(data)?) - } - v4::ToEnvoy::ToEnvoyTunnelMessage(data) => { - v5::ToEnvoy::ToEnvoyTunnelMessage(convert_same_bytes(data)?) - } - v4::ToEnvoy::ToEnvoyPing(data) => v5::ToEnvoy::ToEnvoyPing(convert_same_bytes(data)?), - v4::ToEnvoy::ToEnvoySqliteGetPagesResponse(data) => { - v5::ToEnvoy::ToEnvoySqliteGetPagesResponse(v5::ToEnvoySqliteGetPagesResponse { - request_id: data.request_id, - data: convert_sqlite_get_pages_response_v4_to_v5(data.data)?, - }) - } - v4::ToEnvoy::ToEnvoySqliteCommitResponse(data) => { - v5::ToEnvoy::ToEnvoySqliteCommitResponse(v5::ToEnvoySqliteCommitResponse { - request_id: data.request_id, - data: convert_sqlite_commit_response_v4_to_v5(data.data)?, - }) - } - v4::ToEnvoy::ToEnvoySqliteExecResponse(data) => { - v5::ToEnvoy::ToEnvoySqliteExecResponse(v5::ToEnvoySqliteExecResponse { - request_id: data.request_id, - data: convert_sqlite_exec_response_v4_to_v5(data.data)?, - }) - } - v4::ToEnvoy::ToEnvoySqliteExecuteResponse(data) => { - v5::ToEnvoy::ToEnvoySqliteExecuteResponse(v5::ToEnvoySqliteExecuteResponse { - request_id: data.request_id, - data: convert_sqlite_execute_response_v4_to_v5(data.data)?, - }) - } - }) -} - -fn convert_to_envoy_v5_to_v4(message: v5::ToEnvoy) -> Result { - Ok(match message { - v5::ToEnvoy::ToEnvoyInit(data) => v4::ToEnvoy::ToEnvoyInit(convert_same_bytes(data)?), - v5::ToEnvoy::ToEnvoyCommands(data) => { - v4::ToEnvoy::ToEnvoyCommands(convert_same_bytes(data)?) - } - v5::ToEnvoy::ToEnvoyAckEvents(data) => { - v4::ToEnvoy::ToEnvoyAckEvents(convert_same_bytes(data)?) - } - v5::ToEnvoy::ToEnvoyKvResponse(data) => { - v4::ToEnvoy::ToEnvoyKvResponse(convert_same_bytes(data)?) - } - v5::ToEnvoy::ToEnvoyTunnelMessage(data) => { - v4::ToEnvoy::ToEnvoyTunnelMessage(convert_same_bytes(data)?) - } - v5::ToEnvoy::ToEnvoyPing(data) => v4::ToEnvoy::ToEnvoyPing(convert_same_bytes(data)?), - v5::ToEnvoy::ToEnvoySqliteGetPagesResponse(data) => { - v4::ToEnvoy::ToEnvoySqliteGetPagesResponse(v4::ToEnvoySqliteGetPagesResponse { - request_id: data.request_id, - data: convert_sqlite_get_pages_response_v5_to_v4(data.data)?, - }) - } - v5::ToEnvoy::ToEnvoySqliteCommitResponse(data) => { - v4::ToEnvoy::ToEnvoySqliteCommitResponse(v4::ToEnvoySqliteCommitResponse { - request_id: data.request_id, - data: convert_sqlite_commit_response_v5_to_v4(data.data)?, - }) - } - v5::ToEnvoy::ToEnvoySqliteExecResponse(data) => { - v4::ToEnvoy::ToEnvoySqliteExecResponse(v4::ToEnvoySqliteExecResponse { - request_id: data.request_id, - data: convert_sqlite_exec_response_v5_to_v4(data.data)?, - }) - } - v5::ToEnvoy::ToEnvoySqliteExecuteResponse(data) => { - v4::ToEnvoy::ToEnvoySqliteExecuteResponse(v4::ToEnvoySqliteExecuteResponse { - request_id: data.request_id, - data: convert_sqlite_execute_response_v5_to_v4(data.data)?, - }) - } - }) -} - -fn convert_sqlite_error_response_v4_to_v5( - error: v4::SqliteErrorResponse, -) -> v5::SqliteErrorResponse { - v5::SqliteErrorResponse { - group: "core".to_string(), - code: "internal_error".to_string(), - message: error.message, - } -} - -fn convert_sqlite_error_response_v5_to_v4( - error: v5::SqliteErrorResponse, -) -> v4::SqliteErrorResponse { - v4::SqliteErrorResponse { - message: error.message, - } -} - -fn convert_sqlite_get_pages_response_v4_to_v5( - message: v4::SqliteGetPagesResponse, -) -> Result { - Ok(match message { - v4::SqliteGetPagesResponse::SqliteGetPagesOk(ok) => { - v5::SqliteGetPagesResponse::SqliteGetPagesOk(v5::SqliteGetPagesOk { - pages: convert_same_bytes(ok.pages)?, - head_txid: None, - }) - } - v4::SqliteGetPagesResponse::SqliteErrorResponse(error) => { - v5::SqliteGetPagesResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v5( - error, - )) - } - }) -} - -fn convert_sqlite_get_pages_response_v5_to_v4( - message: v5::SqliteGetPagesResponse, -) -> Result { - Ok(match message { - v5::SqliteGetPagesResponse::SqliteGetPagesOk(ok) => { - v4::SqliteGetPagesResponse::SqliteGetPagesOk(v4::SqliteGetPagesOk { - pages: convert_same_bytes(ok.pages)?, - }) - } - v5::SqliteGetPagesResponse::SqliteErrorResponse(error) => { - v4::SqliteGetPagesResponse::SqliteErrorResponse(convert_sqlite_error_response_v5_to_v4( - error, - )) - } - }) -} - -fn convert_sqlite_commit_response_v4_to_v5( - message: v4::SqliteCommitResponse, -) -> Result { - Ok(match message { - v4::SqliteCommitResponse::SqliteCommitOk => { - v5::SqliteCommitResponse::SqliteCommitOk(v5::SqliteCommitOk { head_txid: None }) - } - v4::SqliteCommitResponse::SqliteErrorResponse(error) => { - v5::SqliteCommitResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v5( - error, - )) - } - }) -} - -fn convert_sqlite_commit_response_v5_to_v4( - message: v5::SqliteCommitResponse, -) -> Result { - Ok(match message { - v5::SqliteCommitResponse::SqliteCommitOk(_) => v4::SqliteCommitResponse::SqliteCommitOk, - v5::SqliteCommitResponse::SqliteErrorResponse(error) => { - v4::SqliteCommitResponse::SqliteErrorResponse(convert_sqlite_error_response_v5_to_v4( - error, - )) - } - }) -} - -fn convert_sqlite_exec_response_v4_to_v5( - message: v4::SqliteExecResponse, -) -> Result { - Ok(match message { - v4::SqliteExecResponse::SqliteExecOk(ok) => { - v5::SqliteExecResponse::SqliteExecOk(convert_same_bytes(ok)?) - } - v4::SqliteExecResponse::SqliteErrorResponse(error) => { - v5::SqliteExecResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v5( - error, - )) - } - }) -} - -fn convert_sqlite_exec_response_v5_to_v4( - message: v5::SqliteExecResponse, -) -> Result { - Ok(match message { - v5::SqliteExecResponse::SqliteExecOk(ok) => { - v4::SqliteExecResponse::SqliteExecOk(convert_same_bytes(ok)?) - } - v5::SqliteExecResponse::SqliteErrorResponse(error) => { - v4::SqliteExecResponse::SqliteErrorResponse(convert_sqlite_error_response_v5_to_v4( - error, - )) - } - }) -} - -fn convert_sqlite_execute_response_v4_to_v5( - message: v4::SqliteExecuteResponse, -) -> Result { - Ok(match message { - v4::SqliteExecuteResponse::SqliteExecuteOk(ok) => { - v5::SqliteExecuteResponse::SqliteExecuteOk(convert_same_bytes(ok)?) - } - v4::SqliteExecuteResponse::SqliteErrorResponse(error) => { - v5::SqliteExecuteResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v5( - error, - )) - } - }) -} - -fn convert_sqlite_execute_response_v5_to_v4( - message: v5::SqliteExecuteResponse, -) -> Result { - Ok(match message { - v5::SqliteExecuteResponse::SqliteExecuteOk(ok) => { - v4::SqliteExecuteResponse::SqliteExecuteOk(convert_same_bytes(ok)?) - } - v5::SqliteExecuteResponse::SqliteErrorResponse(error) => { - v4::SqliteExecuteResponse::SqliteErrorResponse(convert_sqlite_error_response_v5_to_v4( - error, - )) - } - }) -} - -fn convert_to_rivet_v4_to_v5(message: v4::ToRivet) -> Result { - convert_same_bytes(message) -} - -fn convert_to_rivet_v5_to_v4(message: v5::ToRivet) -> Result { - convert_same_bytes(message) -} - -fn convert_to_envoy_v3_to_v4(message: v3::ToEnvoy) -> Result { - convert_same_bytes(message) -} - -fn convert_to_envoy_v4_to_v3(message: v4::ToEnvoy, target_version: u16) -> Result { - match &message { - v4::ToEnvoy::ToEnvoySqliteExecResponse(_) => { - return Err(incompatible( - ProtocolCompatibilityFeature::RemoteSqliteExecution, - ProtocolCompatibilityDirection::ToEnvoy, - 4, - target_version, - )); - } - v4::ToEnvoy::ToEnvoySqliteExecuteResponse(_) => { - return Err(incompatible( - ProtocolCompatibilityFeature::RemoteSqliteExecution, - ProtocolCompatibilityDirection::ToEnvoy, - 4, - target_version, - )); - } - v4::ToEnvoy::ToEnvoyInit(_) - | v4::ToEnvoy::ToEnvoyCommands(_) - | v4::ToEnvoy::ToEnvoyAckEvents(_) - | v4::ToEnvoy::ToEnvoyKvResponse(_) - | v4::ToEnvoy::ToEnvoyTunnelMessage(_) - | v4::ToEnvoy::ToEnvoyPing(_) - | v4::ToEnvoy::ToEnvoySqliteGetPagesResponse(_) - | v4::ToEnvoy::ToEnvoySqliteCommitResponse(_) => {} - } - - convert_same_bytes(message) -} - -fn convert_to_rivet_v3_to_v4(message: v3::ToRivet) -> Result { - convert_same_bytes(message) -} - -fn convert_to_rivet_v4_to_v3(message: v4::ToRivet, target_version: u16) -> Result { - match &message { - v4::ToRivet::ToRivetSqliteExecRequest(_) => { - return Err(incompatible( - ProtocolCompatibilityFeature::RemoteSqliteExecution, - ProtocolCompatibilityDirection::ToRivet, - 4, - target_version, - )); - } - v4::ToRivet::ToRivetSqliteExecuteRequest(_) => { - return Err(incompatible( - ProtocolCompatibilityFeature::RemoteSqliteExecution, - ProtocolCompatibilityDirection::ToRivet, - 4, - target_version, - )); - } - v4::ToRivet::ToRivetMetadata(_) - | v4::ToRivet::ToRivetEvents(_) - | v4::ToRivet::ToRivetAckCommands(_) - | v4::ToRivet::ToRivetStopping - | v4::ToRivet::ToRivetPong(_) - | v4::ToRivet::ToRivetKvRequest(_) - | v4::ToRivet::ToRivetTunnelMessage(_) - | v4::ToRivet::ToRivetSqliteGetPagesRequest(_) - | v4::ToRivet::ToRivetSqliteCommitRequest(_) => {} - } - - convert_same_bytes(message) -} - -fn convert_to_envoy_v2_to_v3(message: v2::ToEnvoy) -> Result { - Ok(match message { - v2::ToEnvoy::ToEnvoyInit(init) => v3::ToEnvoy::ToEnvoyInit(v3::ToEnvoyInit { - metadata: convert_protocol_metadata_v2_to_v3(init.metadata), - }), - v2::ToEnvoy::ToEnvoyCommands(commands) => v3::ToEnvoy::ToEnvoyCommands( - commands - .into_iter() - .map(convert_command_wrapper_v2_to_v3) - .collect(), - ), - v2::ToEnvoy::ToEnvoyAckEvents(ack) => { - v3::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v2_to_v3(ack)) - } - v2::ToEnvoy::ToEnvoyKvResponse(response) => { - v3::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v2_to_v3(response)) - } - v2::ToEnvoy::ToEnvoyTunnelMessage(message) => { - v3::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v2_to_v3(message)) - } - v2::ToEnvoy::ToEnvoyPing(ping) => v3::ToEnvoy::ToEnvoyPing(v3::ToEnvoyPing { ts: ping.ts }), - v2::ToEnvoy::ToEnvoySqliteGetPagesResponse(_) - | v2::ToEnvoy::ToEnvoySqliteCommitResponse(_) - | v2::ToEnvoy::ToEnvoySqliteCommitStageBeginResponse(_) - | v2::ToEnvoy::ToEnvoySqliteCommitStageResponse(_) - | v2::ToEnvoy::ToEnvoySqliteCommitFinalizeResponse(_) => { - bail!("legacy sqlite responses require envoy-protocol v2") - } - }) -} - -fn convert_to_envoy_v3_to_v2(message: v3::ToEnvoy) -> Result { - Ok(match message { - v3::ToEnvoy::ToEnvoyInit(init) => v2::ToEnvoy::ToEnvoyInit(v2::ToEnvoyInit { - metadata: convert_protocol_metadata_v3_to_v2(init.metadata), - }), - v3::ToEnvoy::ToEnvoyCommands(commands) => v2::ToEnvoy::ToEnvoyCommands( - commands - .into_iter() - .map(convert_command_wrapper_v3_to_v2) - .collect(), - ), - v3::ToEnvoy::ToEnvoyAckEvents(ack) => { - v2::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v3_to_v2(ack)) - } - v3::ToEnvoy::ToEnvoyKvResponse(response) => { - v2::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v3_to_v2(response)) - } - v3::ToEnvoy::ToEnvoyTunnelMessage(message) => { - v2::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v3_to_v2(message)) - } - v3::ToEnvoy::ToEnvoyPing(ping) => v2::ToEnvoy::ToEnvoyPing(v2::ToEnvoyPing { ts: ping.ts }), - v3::ToEnvoy::ToEnvoySqliteGetPagesResponse(_) - | v3::ToEnvoy::ToEnvoySqliteCommitResponse(_) => { - bail!("stateless sqlite responses require envoy-protocol v3") - } - }) -} - -fn convert_to_rivet_v2_to_v3(message: v2::ToRivet) -> Result { - Ok(match message { - v2::ToRivet::ToRivetMetadata(metadata) => { - v3::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v2_to_v3(metadata)) - } - v2::ToRivet::ToRivetEvents(events) => v3::ToRivet::ToRivetEvents( - events - .into_iter() - .map(convert_event_wrapper_v2_to_v3) - .collect(), - ), - v2::ToRivet::ToRivetAckCommands(ack) => { - v3::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v2_to_v3(ack)) - } - v2::ToRivet::ToRivetStopping => v3::ToRivet::ToRivetStopping, - v2::ToRivet::ToRivetPong(pong) => v3::ToRivet::ToRivetPong(v3::ToRivetPong { ts: pong.ts }), - v2::ToRivet::ToRivetKvRequest(request) => { - v3::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v2_to_v3(request)) - } - v2::ToRivet::ToRivetTunnelMessage(message) => { - v3::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v2_to_v3(message)) - } - v2::ToRivet::ToRivetSqliteGetPagesRequest(_) - | v2::ToRivet::ToRivetSqliteCommitRequest(_) - | v2::ToRivet::ToRivetSqliteCommitStageBeginRequest(_) - | v2::ToRivet::ToRivetSqliteCommitStageRequest(_) - | v2::ToRivet::ToRivetSqliteCommitFinalizeRequest(_) => { - bail!("legacy sqlite requests require envoy-protocol v2") - } - }) -} - -fn convert_to_rivet_v3_to_v2(message: v3::ToRivet) -> Result { - Ok(match message { - v3::ToRivet::ToRivetMetadata(metadata) => { - v2::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v3_to_v2(metadata)) - } - v3::ToRivet::ToRivetEvents(events) => v2::ToRivet::ToRivetEvents( - events - .into_iter() - .map(convert_event_wrapper_v3_to_v2) - .collect(), - ), - v3::ToRivet::ToRivetAckCommands(ack) => { - v2::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v3_to_v2(ack)) - } - v3::ToRivet::ToRivetStopping => v2::ToRivet::ToRivetStopping, - v3::ToRivet::ToRivetPong(pong) => v2::ToRivet::ToRivetPong(v2::ToRivetPong { ts: pong.ts }), - v3::ToRivet::ToRivetKvRequest(request) => { - v2::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v3_to_v2(request)) - } - v3::ToRivet::ToRivetTunnelMessage(message) => { - v2::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v3_to_v2(message)) - } - v3::ToRivet::ToRivetSqliteGetPagesRequest(_) - | v3::ToRivet::ToRivetSqliteCommitRequest(_) => { - bail!("stateless sqlite requests require envoy-protocol v3") - } - }) -} - -fn convert_to_envoy_conn_v1_to_v3(message: v1::ToEnvoyConn) -> Result { - Ok(match message { - v1::ToEnvoyConn::ToEnvoyConnPing(ping) => { - v3::ToEnvoyConn::ToEnvoyConnPing(v3::ToEnvoyConnPing { - gateway_id: ping.gateway_id, - request_id: ping.request_id, - ts: ping.ts, - }) - } - v1::ToEnvoyConn::ToEnvoyConnClose => v3::ToEnvoyConn::ToEnvoyConnClose, - v1::ToEnvoyConn::ToEnvoyCommands(commands) => v3::ToEnvoyConn::ToEnvoyCommands( - commands - .into_iter() - .map(convert_command_wrapper_v1_to_v3) - .collect(), - ), - v1::ToEnvoyConn::ToEnvoyAckEvents(ack) => { - v3::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v1_to_v3(ack)) - } - v1::ToEnvoyConn::ToEnvoyTunnelMessage(message) => { - v3::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v1_to_v3(message)) - } - }) -} - -fn convert_to_envoy_conn_v2_to_v3(message: v2::ToEnvoyConn) -> Result { - Ok(match message { - v2::ToEnvoyConn::ToEnvoyConnPing(ping) => { - v3::ToEnvoyConn::ToEnvoyConnPing(v3::ToEnvoyConnPing { - gateway_id: ping.gateway_id, - request_id: ping.request_id, - ts: ping.ts, - }) - } - v2::ToEnvoyConn::ToEnvoyConnClose => v3::ToEnvoyConn::ToEnvoyConnClose, - v2::ToEnvoyConn::ToEnvoyCommands(commands) => v3::ToEnvoyConn::ToEnvoyCommands( - commands - .into_iter() - .map(convert_command_wrapper_v2_to_v3) - .collect(), - ), - v2::ToEnvoyConn::ToEnvoyAckEvents(ack) => { - v3::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v2_to_v3(ack)) - } - v2::ToEnvoyConn::ToEnvoyTunnelMessage(message) => { - v3::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v2_to_v3(message)) - } - }) -} - -fn convert_to_envoy_conn_v3_to_v1(message: v3::ToEnvoyConn) -> Result { - Ok(match message { - v3::ToEnvoyConn::ToEnvoyConnPing(ping) => { - v1::ToEnvoyConn::ToEnvoyConnPing(v1::ToEnvoyConnPing { - gateway_id: ping.gateway_id, - request_id: ping.request_id, - ts: ping.ts, - }) - } - v3::ToEnvoyConn::ToEnvoyConnClose => v1::ToEnvoyConn::ToEnvoyConnClose, - v3::ToEnvoyConn::ToEnvoyCommands(commands) => v1::ToEnvoyConn::ToEnvoyCommands( - commands - .into_iter() - .map(convert_command_wrapper_v3_to_v1) - .collect(), - ), - v3::ToEnvoyConn::ToEnvoyAckEvents(ack) => { - v1::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v3_to_v1(ack)) - } - v3::ToEnvoyConn::ToEnvoyTunnelMessage(message) => { - v1::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v3_to_v1(message)) - } - }) -} - -fn convert_to_envoy_conn_v3_to_v2(message: v3::ToEnvoyConn) -> Result { - Ok(match message { - v3::ToEnvoyConn::ToEnvoyConnPing(ping) => { - v2::ToEnvoyConn::ToEnvoyConnPing(v2::ToEnvoyConnPing { - gateway_id: ping.gateway_id, - request_id: ping.request_id, - ts: ping.ts, - }) - } - v3::ToEnvoyConn::ToEnvoyConnClose => v2::ToEnvoyConn::ToEnvoyConnClose, - v3::ToEnvoyConn::ToEnvoyCommands(commands) => v2::ToEnvoyConn::ToEnvoyCommands( - commands - .into_iter() - .map(convert_command_wrapper_v3_to_v2) - .collect(), - ), - v3::ToEnvoyConn::ToEnvoyAckEvents(ack) => { - v2::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v3_to_v2(ack)) - } - v3::ToEnvoyConn::ToEnvoyTunnelMessage(message) => { - v2::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v3_to_v2(message)) - } - }) -} - -fn convert_to_gateway_v1_to_v3(message: v1::ToGateway) -> v3::ToGateway { - match message { - v1::ToGateway::ToGatewayPong(pong) => v3::ToGateway::ToGatewayPong(v3::ToGatewayPong { - request_id: pong.request_id, - ts: pong.ts, - }), - v1::ToGateway::ToRivetTunnelMessage(message) => { - v3::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v1_to_v3(message)) - } - } -} - -fn convert_to_gateway_v2_to_v3(message: v2::ToGateway) -> v3::ToGateway { - match message { - v2::ToGateway::ToGatewayPong(pong) => v3::ToGateway::ToGatewayPong(v3::ToGatewayPong { - request_id: pong.request_id, - ts: pong.ts, - }), - v2::ToGateway::ToRivetTunnelMessage(message) => { - v3::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v2_to_v3(message)) - } - } -} - -fn convert_to_gateway_v3_to_v1(message: v3::ToGateway) -> v1::ToGateway { - match message { - v3::ToGateway::ToGatewayPong(pong) => v1::ToGateway::ToGatewayPong(v1::ToGatewayPong { - request_id: pong.request_id, - ts: pong.ts, - }), - v3::ToGateway::ToRivetTunnelMessage(message) => { - v1::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v3_to_v1(message)) - } - } -} - -fn convert_to_gateway_v3_to_v2(message: v3::ToGateway) -> v2::ToGateway { - match message { - v3::ToGateway::ToGatewayPong(pong) => v2::ToGateway::ToGatewayPong(v2::ToGatewayPong { - request_id: pong.request_id, - ts: pong.ts, - }), - v3::ToGateway::ToRivetTunnelMessage(message) => { - v2::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v3_to_v2(message)) - } - } -} - -fn convert_to_outbound_v1_to_v3(message: v1::ToOutbound) -> v3::ToOutbound { - match message { - v1::ToOutbound::ToOutboundActorStart(start) => { - v3::ToOutbound::ToOutboundActorStart(v3::ToOutboundActorStart { - namespace_id: start.namespace_id, - pool_name: start.pool_name, - checkpoint: convert_actor_checkpoint_v1_to_v3(start.checkpoint), - actor_config: convert_actor_config_v1_to_v3(start.actor_config), - }) - } - } -} - -fn convert_to_outbound_v2_to_v3(message: v2::ToOutbound) -> v3::ToOutbound { - match message { - v2::ToOutbound::ToOutboundActorStart(start) => { - v3::ToOutbound::ToOutboundActorStart(v3::ToOutboundActorStart { - namespace_id: start.namespace_id, - pool_name: start.pool_name, - checkpoint: convert_actor_checkpoint_v2_to_v3(start.checkpoint), - actor_config: convert_actor_config_v2_to_v3(start.actor_config), - }) - } - } -} - -fn convert_to_outbound_v3_to_v1(message: v3::ToOutbound) -> v1::ToOutbound { - match message { - v3::ToOutbound::ToOutboundActorStart(start) => { - v1::ToOutbound::ToOutboundActorStart(v1::ToOutboundActorStart { - namespace_id: start.namespace_id, - pool_name: start.pool_name, - checkpoint: convert_actor_checkpoint_v3_to_v1(start.checkpoint), - actor_config: convert_actor_config_v3_to_v1(start.actor_config), - }) - } - } -} - -fn convert_to_outbound_v3_to_v2(message: v3::ToOutbound) -> v2::ToOutbound { - match message { - v3::ToOutbound::ToOutboundActorStart(start) => { - v2::ToOutbound::ToOutboundActorStart(v2::ToOutboundActorStart { - namespace_id: start.namespace_id, - pool_name: start.pool_name, - checkpoint: convert_actor_checkpoint_v3_to_v2(start.checkpoint), - actor_config: convert_actor_config_v3_to_v2(start.actor_config), - }) - } - } -} - -fn convert_to_envoy_v1_to_v2(message: v1::ToEnvoy) -> Result { - Ok(match message { - v1::ToEnvoy::ToEnvoyCommands(commands) => v2::ToEnvoy::ToEnvoyCommands( - commands - .into_iter() - .map(convert_command_wrapper_v1_to_v2) - .collect::>>()?, - ), - v1::ToEnvoy::ToEnvoyInit(init) => v2::ToEnvoy::ToEnvoyInit(v2::ToEnvoyInit { - metadata: convert_protocol_metadata_v1_to_v2(init.metadata), - }), - v1::ToEnvoy::ToEnvoyAckEvents(ack) => { - v2::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v1_to_v2(ack)) - } - v1::ToEnvoy::ToEnvoyKvResponse(response) => { - v2::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v1_to_v2(response)) - } - v1::ToEnvoy::ToEnvoyTunnelMessage(message) => { - v2::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v1_to_v2(message)) - } - v1::ToEnvoy::ToEnvoyPing(ping) => v2::ToEnvoy::ToEnvoyPing(v2::ToEnvoyPing { ts: ping.ts }), - }) -} - -fn convert_to_envoy_v2_to_v1(message: v2::ToEnvoy) -> Result { - Ok(match message { - v2::ToEnvoy::ToEnvoyCommands(commands) => v1::ToEnvoy::ToEnvoyCommands( - commands - .into_iter() - .map(convert_command_wrapper_v2_to_v1) - .collect::>>()?, - ), - v2::ToEnvoy::ToEnvoyInit(init) => v1::ToEnvoy::ToEnvoyInit(v1::ToEnvoyInit { - metadata: convert_protocol_metadata_v2_to_v1(init.metadata), - }), - v2::ToEnvoy::ToEnvoyAckEvents(ack) => { - v1::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v2_to_v1(ack)) - } - v2::ToEnvoy::ToEnvoyKvResponse(response) => { - v1::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v2_to_v1(response)) - } - v2::ToEnvoy::ToEnvoyTunnelMessage(message) => { - v1::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v2_to_v1(message)) - } - v2::ToEnvoy::ToEnvoyPing(ping) => v1::ToEnvoy::ToEnvoyPing(v1::ToEnvoyPing { ts: ping.ts }), - v2::ToEnvoy::ToEnvoySqliteGetPagesResponse(_) - | v2::ToEnvoy::ToEnvoySqliteCommitResponse(_) - | v2::ToEnvoy::ToEnvoySqliteCommitStageBeginResponse(_) - | v2::ToEnvoy::ToEnvoySqliteCommitStageResponse(_) - | v2::ToEnvoy::ToEnvoySqliteCommitFinalizeResponse(_) => { - bail!("sqlite responses require envoy-protocol v2") - } - }) -} - -fn convert_command_wrapper_v1_to_v2(wrapper: v1::CommandWrapper) -> Result { - Ok(v2::CommandWrapper { - checkpoint: convert_actor_checkpoint_v1_to_v2(wrapper.checkpoint), - inner: convert_command_v1_to_v2(wrapper.inner)?, - }) -} - -fn convert_command_wrapper_v2_to_v1(wrapper: v2::CommandWrapper) -> Result { - Ok(v1::CommandWrapper { - checkpoint: convert_actor_checkpoint_v2_to_v1(wrapper.checkpoint), - inner: convert_command_v2_to_v1(wrapper.inner)?, - }) -} - -fn convert_command_wrapper_v1_to_v3(wrapper: v1::CommandWrapper) -> v3::CommandWrapper { - v3::CommandWrapper { - checkpoint: convert_actor_checkpoint_v1_to_v3(wrapper.checkpoint), - inner: convert_command_v1_to_v3(wrapper.inner), - } -} - -fn convert_command_wrapper_v2_to_v3(wrapper: v2::CommandWrapper) -> v3::CommandWrapper { - v3::CommandWrapper { - checkpoint: convert_actor_checkpoint_v2_to_v3(wrapper.checkpoint), - inner: convert_command_v2_to_v3(wrapper.inner), - } -} - -fn convert_command_wrapper_v3_to_v1(wrapper: v3::CommandWrapper) -> v1::CommandWrapper { - v1::CommandWrapper { - checkpoint: convert_actor_checkpoint_v3_to_v1(wrapper.checkpoint), - inner: convert_command_v3_to_v1(wrapper.inner), - } -} - -fn convert_command_wrapper_v3_to_v2(wrapper: v3::CommandWrapper) -> v2::CommandWrapper { - v2::CommandWrapper { - checkpoint: convert_actor_checkpoint_v3_to_v2(wrapper.checkpoint), - inner: convert_command_v3_to_v2(wrapper.inner), - } -} - -fn convert_command_v1_to_v2(command: v1::Command) -> Result { - Ok(match command { - v1::Command::CommandStartActor(start) => { - v2::Command::CommandStartActor(convert_command_start_actor_v1_to_v2(start)) - } - v1::Command::CommandStopActor(stop) => { - v2::Command::CommandStopActor(v2::CommandStopActor { - reason: convert_stop_actor_reason_v1_to_v2(stop.reason), - }) - } - }) -} - -fn convert_command_v2_to_v1(command: v2::Command) -> Result { - Ok(match command { - v2::Command::CommandStartActor(start) => { - v1::Command::CommandStartActor(convert_command_start_actor_v2_to_v1(start)?) - } - v2::Command::CommandStopActor(stop) => { - v1::Command::CommandStopActor(v1::CommandStopActor { - reason: convert_stop_actor_reason_v2_to_v1(stop.reason), - }) - } - }) -} - -fn convert_command_v1_to_v3(command: v1::Command) -> v3::Command { - match command { - v1::Command::CommandStartActor(start) => { - v3::Command::CommandStartActor(convert_command_start_actor_v1_to_v3(start)) - } - v1::Command::CommandStopActor(stop) => { - v3::Command::CommandStopActor(v3::CommandStopActor { - reason: convert_stop_actor_reason_v1_to_v3(stop.reason), - }) - } - } -} - -fn convert_command_v2_to_v3(command: v2::Command) -> v3::Command { - match command { - v2::Command::CommandStartActor(start) => { - v3::Command::CommandStartActor(convert_command_start_actor_v2_to_v3(start)) - } - v2::Command::CommandStopActor(stop) => { - v3::Command::CommandStopActor(v3::CommandStopActor { - reason: convert_stop_actor_reason_v2_to_v3(stop.reason), - }) - } - } -} - -fn convert_command_v3_to_v1(command: v3::Command) -> v1::Command { - match command { - v3::Command::CommandStartActor(start) => { - v1::Command::CommandStartActor(convert_command_start_actor_v3_to_v1(start)) - } - v3::Command::CommandStopActor(stop) => { - v1::Command::CommandStopActor(v1::CommandStopActor { - reason: convert_stop_actor_reason_v3_to_v1(stop.reason), - }) - } - } -} - -fn convert_command_v3_to_v2(command: v3::Command) -> v2::Command { - match command { - v3::Command::CommandStartActor(start) => { - v2::Command::CommandStartActor(convert_command_start_actor_v3_to_v2(start)) - } - v3::Command::CommandStopActor(stop) => { - v2::Command::CommandStopActor(v2::CommandStopActor { - reason: convert_stop_actor_reason_v3_to_v2(stop.reason), - }) - } - } -} - -fn convert_command_start_actor_v1_to_v2(start: v1::CommandStartActor) -> v2::CommandStartActor { - v2::CommandStartActor { - config: convert_actor_config_v1_to_v2(start.config), - hibernating_requests: start - .hibernating_requests - .into_iter() - .map(convert_hibernating_request_v1_to_v2) - .collect(), - preloaded_kv: start.preloaded_kv.map(convert_preloaded_kv_v1_to_v2), - sqlite_startup_data: None, - } -} - -fn convert_command_start_actor_v2_to_v1( - start: v2::CommandStartActor, -) -> Result { - if start.sqlite_startup_data.is_some() { - return Err(incompatible( - ProtocolCompatibilityFeature::SqliteStartupData, - ProtocolCompatibilityDirection::ToEnvoy, - 2, - 1, - )); - } - - Ok(v1::CommandStartActor { - config: convert_actor_config_v2_to_v1(start.config), - hibernating_requests: start - .hibernating_requests - .into_iter() - .map(convert_hibernating_request_v2_to_v1) - .collect(), - preloaded_kv: start.preloaded_kv.map(convert_preloaded_kv_v2_to_v1), - }) -} - -fn convert_command_start_actor_v1_to_v3(start: v1::CommandStartActor) -> v3::CommandStartActor { - v3::CommandStartActor { - config: convert_actor_config_v1_to_v3(start.config), - hibernating_requests: start - .hibernating_requests - .into_iter() - .map(convert_hibernating_request_v1_to_v3) - .collect(), - preloaded_kv: start.preloaded_kv.map(convert_preloaded_kv_v1_to_v3), - } -} - -fn convert_command_start_actor_v2_to_v3(start: v2::CommandStartActor) -> v3::CommandStartActor { - v3::CommandStartActor { - config: convert_actor_config_v2_to_v3(start.config), - hibernating_requests: start - .hibernating_requests - .into_iter() - .map(convert_hibernating_request_v2_to_v3) - .collect(), - preloaded_kv: start.preloaded_kv.map(convert_preloaded_kv_v2_to_v3), - } -} - -fn convert_command_start_actor_v3_to_v1(start: v3::CommandStartActor) -> v1::CommandStartActor { - v1::CommandStartActor { - config: convert_actor_config_v3_to_v1(start.config), - hibernating_requests: start - .hibernating_requests - .into_iter() - .map(convert_hibernating_request_v3_to_v1) - .collect(), - preloaded_kv: start.preloaded_kv.map(convert_preloaded_kv_v3_to_v1), - } -} - -fn convert_command_start_actor_v3_to_v2(start: v3::CommandStartActor) -> v2::CommandStartActor { - v2::CommandStartActor { - config: convert_actor_config_v3_to_v2(start.config), - hibernating_requests: start - .hibernating_requests - .into_iter() - .map(convert_hibernating_request_v3_to_v2) - .collect(), - preloaded_kv: start.preloaded_kv.map(convert_preloaded_kv_v3_to_v2), - sqlite_startup_data: None, - } -} - -fn convert_actor_command_key_data_v1_to_v3( - data: v1::ActorCommandKeyData, -) -> v3::ActorCommandKeyData { - match data { - v1::ActorCommandKeyData::CommandStartActor(start) => { - v3::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v1_to_v3(start)) - } - v1::ActorCommandKeyData::CommandStopActor(stop) => { - v3::ActorCommandKeyData::CommandStopActor(v3::CommandStopActor { - reason: convert_stop_actor_reason_v1_to_v3(stop.reason), - }) - } - } -} - -fn convert_actor_command_key_data_v2_to_v3( - data: v2::ActorCommandKeyData, -) -> v3::ActorCommandKeyData { - match data { - v2::ActorCommandKeyData::CommandStartActor(start) => { - v3::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v2_to_v3(start)) - } - v2::ActorCommandKeyData::CommandStopActor(stop) => { - v3::ActorCommandKeyData::CommandStopActor(v3::CommandStopActor { - reason: convert_stop_actor_reason_v2_to_v3(stop.reason), - }) - } - } -} - -fn convert_actor_command_key_data_v3_to_v1( - data: v3::ActorCommandKeyData, -) -> v1::ActorCommandKeyData { - match data { - v3::ActorCommandKeyData::CommandStartActor(start) => { - v1::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v3_to_v1(start)) - } - v3::ActorCommandKeyData::CommandStopActor(stop) => { - v1::ActorCommandKeyData::CommandStopActor(v1::CommandStopActor { - reason: convert_stop_actor_reason_v3_to_v1(stop.reason), - }) - } - } -} - -fn convert_actor_command_key_data_v3_to_v2( - data: v3::ActorCommandKeyData, -) -> v2::ActorCommandKeyData { - match data { - v3::ActorCommandKeyData::CommandStartActor(start) => { - v2::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v3_to_v2(start)) - } - v3::ActorCommandKeyData::CommandStopActor(stop) => { - v2::ActorCommandKeyData::CommandStopActor(v2::CommandStopActor { - reason: convert_stop_actor_reason_v3_to_v2(stop.reason), - }) - } - } -} - -fn convert_protocol_metadata_v1_to_v2(value: v1::ProtocolMetadata) -> v2::ProtocolMetadata { - v2::ProtocolMetadata { - envoy_lost_threshold: value.envoy_lost_threshold, - actor_stop_threshold: value.actor_stop_threshold, - max_response_payload_size: value.max_response_payload_size, - } -} - -fn convert_protocol_metadata_v2_to_v1(value: v2::ProtocolMetadata) -> v1::ProtocolMetadata { - v1::ProtocolMetadata { - envoy_lost_threshold: value.envoy_lost_threshold, - actor_stop_threshold: value.actor_stop_threshold, - max_response_payload_size: value.max_response_payload_size, - } -} - -fn convert_protocol_metadata_v2_to_v3(value: v2::ProtocolMetadata) -> v3::ProtocolMetadata { - v3::ProtocolMetadata { - envoy_lost_threshold: value.envoy_lost_threshold, - actor_stop_threshold: value.actor_stop_threshold, - max_response_payload_size: value.max_response_payload_size, - } -} - -fn convert_protocol_metadata_v3_to_v2(value: v3::ProtocolMetadata) -> v2::ProtocolMetadata { - v2::ProtocolMetadata { - envoy_lost_threshold: value.envoy_lost_threshold, - actor_stop_threshold: value.actor_stop_threshold, - max_response_payload_size: value.max_response_payload_size, - } -} - -fn convert_actor_config_v1_to_v2(value: v1::ActorConfig) -> v2::ActorConfig { - v2::ActorConfig { - name: value.name, - key: value.key, - create_ts: value.create_ts, - input: value.input, - } -} -fn convert_actor_config_v2_to_v1(value: v2::ActorConfig) -> v1::ActorConfig { - v1::ActorConfig { - name: value.name, - key: value.key, - create_ts: value.create_ts, - input: value.input, - } -} -fn convert_actor_config_v1_to_v3(value: v1::ActorConfig) -> v3::ActorConfig { - v3::ActorConfig { - name: value.name, - key: value.key, - create_ts: value.create_ts, - input: value.input, - } -} -fn convert_actor_config_v2_to_v3(value: v2::ActorConfig) -> v3::ActorConfig { - v3::ActorConfig { - name: value.name, - key: value.key, - create_ts: value.create_ts, - input: value.input, - } -} -fn convert_actor_config_v3_to_v1(value: v3::ActorConfig) -> v1::ActorConfig { - v1::ActorConfig { - name: value.name, - key: value.key, - create_ts: value.create_ts, - input: value.input, - } -} -fn convert_actor_config_v3_to_v2(value: v3::ActorConfig) -> v2::ActorConfig { - v2::ActorConfig { - name: value.name, - key: value.key, - create_ts: value.create_ts, - input: value.input, - } -} - -fn convert_actor_checkpoint_v1_to_v2(value: v1::ActorCheckpoint) -> v2::ActorCheckpoint { - v2::ActorCheckpoint { - actor_id: value.actor_id, - generation: value.generation, - index: value.index, - } -} -fn convert_actor_checkpoint_v2_to_v1(value: v2::ActorCheckpoint) -> v1::ActorCheckpoint { - v1::ActorCheckpoint { - actor_id: value.actor_id, - generation: value.generation, - index: value.index, - } -} -fn convert_actor_checkpoint_v1_to_v3(value: v1::ActorCheckpoint) -> v3::ActorCheckpoint { - v3::ActorCheckpoint { - actor_id: value.actor_id, - generation: value.generation, - index: value.index, - } -} -fn convert_actor_checkpoint_v2_to_v3(value: v2::ActorCheckpoint) -> v3::ActorCheckpoint { - v3::ActorCheckpoint { - actor_id: value.actor_id, - generation: value.generation, - index: value.index, - } -} -fn convert_actor_checkpoint_v3_to_v1(value: v3::ActorCheckpoint) -> v1::ActorCheckpoint { - v1::ActorCheckpoint { - actor_id: value.actor_id, - generation: value.generation, - index: value.index, - } -} -fn convert_actor_checkpoint_v3_to_v2(value: v3::ActorCheckpoint) -> v2::ActorCheckpoint { - v2::ActorCheckpoint { - actor_id: value.actor_id, - generation: value.generation, - index: value.index, - } -} - -fn convert_hibernating_request_v1_to_v2(value: v1::HibernatingRequest) -> v2::HibernatingRequest { - v2::HibernatingRequest { - gateway_id: value.gateway_id, - request_id: value.request_id, - } -} -fn convert_hibernating_request_v2_to_v1(value: v2::HibernatingRequest) -> v1::HibernatingRequest { - v1::HibernatingRequest { - gateway_id: value.gateway_id, - request_id: value.request_id, - } -} -fn convert_hibernating_request_v1_to_v3(value: v1::HibernatingRequest) -> v3::HibernatingRequest { - v3::HibernatingRequest { - gateway_id: value.gateway_id, - request_id: value.request_id, - } -} -fn convert_hibernating_request_v2_to_v3(value: v2::HibernatingRequest) -> v3::HibernatingRequest { - v3::HibernatingRequest { - gateway_id: value.gateway_id, - request_id: value.request_id, - } -} -fn convert_hibernating_request_v3_to_v1(value: v3::HibernatingRequest) -> v1::HibernatingRequest { - v1::HibernatingRequest { - gateway_id: value.gateway_id, - request_id: value.request_id, - } -} -fn convert_hibernating_request_v3_to_v2(value: v3::HibernatingRequest) -> v2::HibernatingRequest { - v2::HibernatingRequest { - gateway_id: value.gateway_id, - request_id: value.request_id, - } -} - -fn convert_preloaded_kv_v1_to_v2(preloaded: v1::PreloadedKv) -> v2::PreloadedKv { - v2::PreloadedKv { - entries: preloaded - .entries - .into_iter() - .map(convert_preloaded_kv_entry_v1_to_v2) - .collect(), - requested_get_keys: preloaded.requested_get_keys, - requested_prefixes: preloaded.requested_prefixes, - } -} -fn convert_preloaded_kv_v2_to_v1(preloaded: v2::PreloadedKv) -> v1::PreloadedKv { - v1::PreloadedKv { - entries: preloaded - .entries - .into_iter() - .map(convert_preloaded_kv_entry_v2_to_v1) - .collect(), - requested_get_keys: preloaded.requested_get_keys, - requested_prefixes: preloaded.requested_prefixes, - } -} -fn convert_preloaded_kv_v1_to_v3(preloaded: v1::PreloadedKv) -> v3::PreloadedKv { - v3::PreloadedKv { - entries: preloaded - .entries - .into_iter() - .map(convert_preloaded_kv_entry_v1_to_v3) - .collect(), - requested_get_keys: preloaded.requested_get_keys, - requested_prefixes: preloaded.requested_prefixes, - } -} -fn convert_preloaded_kv_v2_to_v3(preloaded: v2::PreloadedKv) -> v3::PreloadedKv { - v3::PreloadedKv { - entries: preloaded - .entries - .into_iter() - .map(convert_preloaded_kv_entry_v2_to_v3) - .collect(), - requested_get_keys: preloaded.requested_get_keys, - requested_prefixes: preloaded.requested_prefixes, - } -} -fn convert_preloaded_kv_v3_to_v1(preloaded: v3::PreloadedKv) -> v1::PreloadedKv { - v1::PreloadedKv { - entries: preloaded - .entries - .into_iter() - .map(convert_preloaded_kv_entry_v3_to_v1) - .collect(), - requested_get_keys: preloaded.requested_get_keys, - requested_prefixes: preloaded.requested_prefixes, - } -} -fn convert_preloaded_kv_v3_to_v2(preloaded: v3::PreloadedKv) -> v2::PreloadedKv { - v2::PreloadedKv { - entries: preloaded - .entries - .into_iter() - .map(convert_preloaded_kv_entry_v3_to_v2) - .collect(), - requested_get_keys: preloaded.requested_get_keys, - requested_prefixes: preloaded.requested_prefixes, - } -} - -fn convert_preloaded_kv_entry_v1_to_v2(entry: v1::PreloadedKvEntry) -> v2::PreloadedKvEntry { - v2::PreloadedKvEntry { - key: entry.key, - value: entry.value, - metadata: convert_kv_metadata_v1_to_v2(entry.metadata), - } -} -fn convert_preloaded_kv_entry_v2_to_v1(entry: v2::PreloadedKvEntry) -> v1::PreloadedKvEntry { - v1::PreloadedKvEntry { - key: entry.key, - value: entry.value, - metadata: convert_kv_metadata_v2_to_v1(entry.metadata), - } -} -fn convert_preloaded_kv_entry_v1_to_v3(entry: v1::PreloadedKvEntry) -> v3::PreloadedKvEntry { - v3::PreloadedKvEntry { - key: entry.key, - value: entry.value, - metadata: convert_kv_metadata_v1_to_v3(entry.metadata), - } -} -fn convert_preloaded_kv_entry_v2_to_v3(entry: v2::PreloadedKvEntry) -> v3::PreloadedKvEntry { - v3::PreloadedKvEntry { - key: entry.key, - value: entry.value, - metadata: convert_kv_metadata_v2_to_v3(entry.metadata), - } -} -fn convert_preloaded_kv_entry_v3_to_v1(entry: v3::PreloadedKvEntry) -> v1::PreloadedKvEntry { - v1::PreloadedKvEntry { - key: entry.key, - value: entry.value, - metadata: convert_kv_metadata_v3_to_v1(entry.metadata), - } -} -fn convert_preloaded_kv_entry_v3_to_v2(entry: v3::PreloadedKvEntry) -> v2::PreloadedKvEntry { - v2::PreloadedKvEntry { - key: entry.key, - value: entry.value, - metadata: convert_kv_metadata_v3_to_v2(entry.metadata), - } -} - -fn convert_kv_metadata_v1_to_v2(value: v1::KvMetadata) -> v2::KvMetadata { - v2::KvMetadata { - version: value.version, - update_ts: value.update_ts, - } -} -fn convert_kv_metadata_v2_to_v1(value: v2::KvMetadata) -> v1::KvMetadata { - v1::KvMetadata { - version: value.version, - update_ts: value.update_ts, - } -} -fn convert_kv_metadata_v1_to_v3(value: v1::KvMetadata) -> v3::KvMetadata { - v3::KvMetadata { - version: value.version, - update_ts: value.update_ts, - } -} -fn convert_kv_metadata_v2_to_v3(value: v2::KvMetadata) -> v3::KvMetadata { - v3::KvMetadata { - version: value.version, - update_ts: value.update_ts, - } -} -fn convert_kv_metadata_v3_to_v1(value: v3::KvMetadata) -> v1::KvMetadata { - v1::KvMetadata { - version: value.version, - update_ts: value.update_ts, - } -} -fn convert_kv_metadata_v3_to_v2(value: v3::KvMetadata) -> v2::KvMetadata { - v2::KvMetadata { - version: value.version, - update_ts: value.update_ts, - } -} - -include!("versioned_conversions.in"); - -#[cfg(test)] -mod tests { - use anyhow::Result; - use vbare::OwnedVersionedData; - - use super::{ActorCommandKeyData, ToEnvoy}; - use crate::{ - PROTOCOL_VERSION, - generated::{v1, v2, v5}, - }; - - #[test] - fn protocol_version_constant_matches_schema_version() { - assert_eq!(PROTOCOL_VERSION, 5); - } - - #[test] - fn v1_start_command_deserializes_into_v3_without_sqlite_startup_data() -> Result<()> { - let payload = - serde_bare::to_vec(&v1::ToEnvoy::ToEnvoyCommands(vec![v1::CommandWrapper { - checkpoint: v1::ActorCheckpoint { - actor_id: "actor".into(), - generation: 7, - index: 3, - }, - inner: v1::Command::CommandStartActor(v1::CommandStartActor { - config: v1::ActorConfig { - name: "demo".into(), - key: Some("key".into()), - create_ts: 42, - input: None, - }, - hibernating_requests: Vec::new(), - preloaded_kv: None, - }), - }]))?; - - let decoded = ToEnvoy::deserialize_version(&payload, 1)?.unwrap_latest()?; - let v5::ToEnvoy::ToEnvoyCommands(commands) = decoded else { - panic!("expected commands"); - }; - let v5::Command::CommandStartActor(start) = &commands[0].inner else { - panic!("expected start actor"); - }; - - assert!(start.preloaded_kv.is_none()); - assert_eq!(commands[0].checkpoint.generation, 7); - - Ok(()) - } - - #[test] - fn v2_sqlite_response_does_not_deserialize_to_stateless_protocol() -> Result<()> { - let payload = serde_bare::to_vec(&v2::ToEnvoy::ToEnvoySqliteCommitResponse( - v2::ToEnvoySqliteCommitResponse { - request_id: 1, - data: v2::SqliteCommitResponse::SqliteErrorResponse(v2::SqliteErrorResponse { - message: "old sqlite".into(), - }), - }, - ))?; - - assert!(ToEnvoy::deserialize_version(&payload, 2).is_err()); - Ok(()) - } - - #[test] - fn actor_command_key_data_round_trips_to_v1() -> Result<()> { - let encoded = ActorCommandKeyData::wrap_latest(v5::ActorCommandKeyData::CommandStartActor( - v5::CommandStartActor { - config: v5::ActorConfig { - name: "demo".into(), - key: None, - create_ts: 7, - input: None, - }, - hibernating_requests: Vec::new(), - preloaded_kv: None, - }, - )) - .serialize_version(1)?; - - let decoded = ActorCommandKeyData::deserialize_version(&encoded, 1)?.unwrap_latest()?; - let v5::ActorCommandKeyData::CommandStartActor(start) = decoded else { - panic!("expected start actor"); - }; - assert_eq!(start.config.name, "demo"); - - Ok(()) - } -} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned/mod.rs b/engine/sdks/rust/envoy-protocol/src/versioned/mod.rs new file mode 100644 index 0000000000..7f945fc9b9 --- /dev/null +++ b/engine/sdks/rust/envoy-protocol/src/versioned/mod.rs @@ -0,0 +1,895 @@ +use std::{error::Error, fmt}; + +use anyhow::{Result, bail}; +use vbare::OwnedVersionedData; + +use crate::generated::{v1, v2, v3, v4, v5}; + +mod v1_to_v2; +mod v2_to_v1; +mod v2_to_v3; +mod v3_to_v2; +mod v3_to_v4; +mod v4_to_v3; +mod v4_to_v5; +mod v5_to_v4; + +// MARK: Protocol compatibility errors + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ProtocolCompatibilityFeature { + SqliteStartupData, + SqlitePageIo, + SqlitePageRange, + RemoteSqliteExecution, +} + +impl ProtocolCompatibilityFeature { + fn description(self, direction: ProtocolCompatibilityDirection) -> &'static str { + match self { + ProtocolCompatibilityFeature::SqliteStartupData => "sqlite startup data", + ProtocolCompatibilityFeature::SqlitePageIo => match direction { + ProtocolCompatibilityDirection::ToEnvoy => "sqlite responses", + ProtocolCompatibilityDirection::ToRivet => "sqlite requests", + }, + ProtocolCompatibilityFeature::SqlitePageRange => match direction { + ProtocolCompatibilityDirection::ToEnvoy => "sqlite range responses", + ProtocolCompatibilityDirection::ToRivet => "sqlite range requests", + }, + ProtocolCompatibilityFeature::RemoteSqliteExecution => match direction { + ProtocolCompatibilityDirection::ToEnvoy => "remote sqlite responses", + ProtocolCompatibilityDirection::ToRivet => "remote sqlite requests", + }, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ProtocolCompatibilityDirection { + ToEnvoy, + ToRivet, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct ProtocolCompatibilityError { + pub feature: ProtocolCompatibilityFeature, + pub direction: ProtocolCompatibilityDirection, + pub required_version: u16, + pub target_version: u16, +} + +impl fmt::Display for ProtocolCompatibilityError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let verb = match self.feature { + ProtocolCompatibilityFeature::SqliteStartupData => "requires", + ProtocolCompatibilityFeature::SqlitePageIo + | ProtocolCompatibilityFeature::SqlitePageRange + | ProtocolCompatibilityFeature::RemoteSqliteExecution => "require", + }; + write!( + f, + "{} {} envoy-protocol v{} but target version is v{}", + self.feature.description(self.direction), + verb, + self.required_version, + self.target_version, + ) + } +} + +impl Error for ProtocolCompatibilityError {} + +pub(crate) fn incompatible( + feature: ProtocolCompatibilityFeature, + direction: ProtocolCompatibilityDirection, + required_version: u16, + target_version: u16, +) -> anyhow::Error { + ProtocolCompatibilityError { + feature, + direction, + required_version, + target_version, + } + .into() +} + +// MARK: ToEnvoy + +pub enum ToEnvoy { + V1(v1::ToEnvoy), + V2(v2::ToEnvoy), + V3(v3::ToEnvoy), + V4(v4::ToEnvoy), + V5(v5::ToEnvoy), +} + +impl OwnedVersionedData for ToEnvoy { + type Latest = v5::ToEnvoy; + + fn wrap_latest(latest: Self::Latest) -> Self { + Self::V5(latest) + } + + fn unwrap_latest(self) -> Result { + match self { + Self::V5(x) => Ok(x), + _ => bail!("version not latest"), + } + } + + fn deserialize_version(payload: &[u8], version: u16) -> Result { + match version { + 1 => Ok(Self::V1(serde_bare::from_slice(payload)?)), + 2 => Ok(Self::V2(serde_bare::from_slice(payload)?)), + 3 => Ok(Self::V3(serde_bare::from_slice(payload)?)), + 4 => Ok(Self::V4(serde_bare::from_slice(payload)?)), + 5 => Ok(Self::V5(serde_bare::from_slice(payload)?)), + _ => bail!("invalid version: {version}"), + } + } + + fn serialize_version(self, _version: u16) -> Result> { + match self { + Self::V1(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V2(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V3(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V4(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V5(x) => serde_bare::to_vec(&x).map_err(Into::into), + } + } + + fn deserialize_converters() -> Vec Result> { + vec![ + Self::v1_to_v2, + Self::v2_to_v3, + Self::v3_to_v4, + Self::v4_to_v5, + ] + } + + fn serialize_converters() -> Vec Result> { + vec![ + Self::v5_to_v4, + Self::v4_to_v3, + Self::v3_to_v2, + Self::v2_to_v1, + ] + } +} + +impl ToEnvoy { + fn v1_to_v2(self) -> Result { + match self { + Self::V1(x) => Ok(Self::V2(v1_to_v2::convert_to_envoy_v1_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v1(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V1(v2_to_v1::convert_to_envoy_v2_to_v1(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v3(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V3(v2_to_v3::convert_to_envoy_v2_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v2(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V2(v3_to_v2::convert_to_envoy_v3_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v4(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V4(v3_to_v4::convert_to_envoy_v3_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v3(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V3(v4_to_v3::convert_to_envoy_v4_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v5(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V5(v4_to_v5::convert_to_envoy_v4_to_v5(x)?)), + _ => bail!("unexpected version"), + } + } + fn v5_to_v4(self) -> Result { + match self { + Self::V5(x) => Ok(Self::V4(v5_to_v4::convert_to_envoy_v5_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } +} + +// MARK: ToRivet + +pub enum ToRivet { + V1(v1::ToRivet), + V2(v2::ToRivet), + V3(v3::ToRivet), + V4(v4::ToRivet), + V5(v5::ToRivet), +} + +impl OwnedVersionedData for ToRivet { + type Latest = v5::ToRivet; + + fn wrap_latest(latest: Self::Latest) -> Self { + Self::V5(latest) + } + + fn unwrap_latest(self) -> Result { + match self { + Self::V5(x) => Ok(x), + _ => bail!("version not latest"), + } + } + + fn deserialize_version(payload: &[u8], version: u16) -> Result { + match version { + 1 => Ok(Self::V1(serde_bare::from_slice(payload)?)), + 2 => Ok(Self::V2(serde_bare::from_slice(payload)?)), + 3 => Ok(Self::V3(serde_bare::from_slice(payload)?)), + 4 => Ok(Self::V4(serde_bare::from_slice(payload)?)), + 5 => Ok(Self::V5(serde_bare::from_slice(payload)?)), + _ => bail!("invalid version: {version}"), + } + } + + fn serialize_version(self, _version: u16) -> Result> { + match self { + Self::V1(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V2(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V3(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V4(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V5(x) => serde_bare::to_vec(&x).map_err(Into::into), + } + } + + fn deserialize_converters() -> Vec Result> { + vec![ + Self::v1_to_v2, + Self::v2_to_v3, + Self::v3_to_v4, + Self::v4_to_v5, + ] + } + + fn serialize_converters() -> Vec Result> { + vec![ + Self::v5_to_v4, + Self::v4_to_v3, + Self::v3_to_v2, + Self::v2_to_v1, + ] + } +} + +impl ToRivet { + fn v1_to_v2(self) -> Result { + match self { + Self::V1(x) => Ok(Self::V2(v1_to_v2::convert_to_rivet_v1_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v1(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V1(v2_to_v1::convert_to_rivet_v2_to_v1(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v3(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V3(v2_to_v3::convert_to_rivet_v2_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v2(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V2(v3_to_v2::convert_to_rivet_v3_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v4(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V4(v3_to_v4::convert_to_rivet_v3_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v3(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V3(v4_to_v3::convert_to_rivet_v4_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v5(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V5(v4_to_v5::convert_to_rivet_v4_to_v5(x)?)), + _ => bail!("unexpected version"), + } + } + fn v5_to_v4(self) -> Result { + match self { + Self::V5(x) => Ok(Self::V4(v5_to_v4::convert_to_rivet_v5_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } +} + +// MARK: ToEnvoyConn + +pub enum ToEnvoyConn { + V1(v1::ToEnvoyConn), + V2(v2::ToEnvoyConn), + V3(v3::ToEnvoyConn), + V4(v4::ToEnvoyConn), + V5(v5::ToEnvoyConn), +} + +impl OwnedVersionedData for ToEnvoyConn { + type Latest = v5::ToEnvoyConn; + + fn wrap_latest(latest: Self::Latest) -> Self { + Self::V5(latest) + } + + fn unwrap_latest(self) -> Result { + match self { + Self::V5(x) => Ok(x), + _ => bail!("version not latest"), + } + } + + fn deserialize_version(payload: &[u8], version: u16) -> Result { + match version { + 1 => Ok(Self::V1(serde_bare::from_slice(payload)?)), + 2 => Ok(Self::V2(serde_bare::from_slice(payload)?)), + 3 => Ok(Self::V3(serde_bare::from_slice(payload)?)), + 4 => Ok(Self::V4(serde_bare::from_slice(payload)?)), + 5 => Ok(Self::V5(serde_bare::from_slice(payload)?)), + _ => bail!("invalid version: {version}"), + } + } + + fn serialize_version(self, _version: u16) -> Result> { + match self { + Self::V1(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V2(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V3(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V4(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V5(x) => serde_bare::to_vec(&x).map_err(Into::into), + } + } + + fn deserialize_converters() -> Vec Result> { + vec![ + Self::v1_to_v2, + Self::v2_to_v3, + Self::v3_to_v4, + Self::v4_to_v5, + ] + } + + fn serialize_converters() -> Vec Result> { + vec![ + Self::v5_to_v4, + Self::v4_to_v3, + Self::v3_to_v2, + Self::v2_to_v1, + ] + } +} + +impl ToEnvoyConn { + fn v1_to_v2(self) -> Result { + match self { + Self::V1(x) => Ok(Self::V2(v1_to_v2::convert_to_envoy_conn_v1_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v1(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V1(v2_to_v1::convert_to_envoy_conn_v2_to_v1(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v3(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V3(v2_to_v3::convert_to_envoy_conn_v2_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v2(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V2(v3_to_v2::convert_to_envoy_conn_v3_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v4(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V4(v3_to_v4::convert_to_envoy_conn_v3_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v3(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V3(v4_to_v3::convert_to_envoy_conn_v4_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v5(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V5(v4_to_v5::convert_to_envoy_conn_v4_to_v5(x)?)), + _ => bail!("unexpected version"), + } + } + fn v5_to_v4(self) -> Result { + match self { + Self::V5(x) => Ok(Self::V4(v5_to_v4::convert_to_envoy_conn_v5_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } +} + +// MARK: ToGateway + +pub enum ToGateway { + V1(v1::ToGateway), + V2(v2::ToGateway), + V3(v3::ToGateway), + V4(v4::ToGateway), + V5(v5::ToGateway), +} + +impl OwnedVersionedData for ToGateway { + type Latest = v5::ToGateway; + + fn wrap_latest(latest: Self::Latest) -> Self { + Self::V5(latest) + } + + fn unwrap_latest(self) -> Result { + match self { + Self::V5(x) => Ok(x), + _ => bail!("version not latest"), + } + } + + fn deserialize_version(payload: &[u8], version: u16) -> Result { + match version { + 1 => Ok(Self::V1(serde_bare::from_slice(payload)?)), + 2 => Ok(Self::V2(serde_bare::from_slice(payload)?)), + 3 => Ok(Self::V3(serde_bare::from_slice(payload)?)), + 4 => Ok(Self::V4(serde_bare::from_slice(payload)?)), + 5 => Ok(Self::V5(serde_bare::from_slice(payload)?)), + _ => bail!("invalid version: {version}"), + } + } + + fn serialize_version(self, _version: u16) -> Result> { + match self { + Self::V1(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V2(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V3(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V4(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V5(x) => serde_bare::to_vec(&x).map_err(Into::into), + } + } + + fn deserialize_converters() -> Vec Result> { + vec![ + Self::v1_to_v2, + Self::v2_to_v3, + Self::v3_to_v4, + Self::v4_to_v5, + ] + } + + fn serialize_converters() -> Vec Result> { + vec![ + Self::v5_to_v4, + Self::v4_to_v3, + Self::v3_to_v2, + Self::v2_to_v1, + ] + } +} + +impl ToGateway { + fn v1_to_v2(self) -> Result { + match self { + Self::V1(x) => Ok(Self::V2(v1_to_v2::convert_to_gateway_v1_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v1(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V1(v2_to_v1::convert_to_gateway_v2_to_v1(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v3(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V3(v2_to_v3::convert_to_gateway_v2_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v2(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V2(v3_to_v2::convert_to_gateway_v3_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v4(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V4(v3_to_v4::convert_to_gateway_v3_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v3(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V3(v4_to_v3::convert_to_gateway_v4_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v5(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V5(v4_to_v5::convert_to_gateway_v4_to_v5(x)?)), + _ => bail!("unexpected version"), + } + } + fn v5_to_v4(self) -> Result { + match self { + Self::V5(x) => Ok(Self::V4(v5_to_v4::convert_to_gateway_v5_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } +} + +// MARK: ToOutbound + +pub enum ToOutbound { + V1(v1::ToOutbound), + V2(v2::ToOutbound), + V3(v3::ToOutbound), + V4(v4::ToOutbound), + V5(v5::ToOutbound), +} + +impl OwnedVersionedData for ToOutbound { + type Latest = v5::ToOutbound; + + fn wrap_latest(latest: Self::Latest) -> Self { + Self::V5(latest) + } + + fn unwrap_latest(self) -> Result { + match self { + Self::V5(x) => Ok(x), + _ => bail!("version not latest"), + } + } + + fn deserialize_version(payload: &[u8], version: u16) -> Result { + match version { + 1 => Ok(Self::V1(serde_bare::from_slice(payload)?)), + 2 => Ok(Self::V2(serde_bare::from_slice(payload)?)), + 3 => Ok(Self::V3(serde_bare::from_slice(payload)?)), + 4 => Ok(Self::V4(serde_bare::from_slice(payload)?)), + 5 => Ok(Self::V5(serde_bare::from_slice(payload)?)), + _ => bail!("invalid version: {version}"), + } + } + + fn serialize_version(self, _version: u16) -> Result> { + match self { + Self::V1(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V2(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V3(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V4(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V5(x) => serde_bare::to_vec(&x).map_err(Into::into), + } + } + + fn deserialize_converters() -> Vec Result> { + vec![ + Self::v1_to_v2, + Self::v2_to_v3, + Self::v3_to_v4, + Self::v4_to_v5, + ] + } + + fn serialize_converters() -> Vec Result> { + vec![ + Self::v5_to_v4, + Self::v4_to_v3, + Self::v3_to_v2, + Self::v2_to_v1, + ] + } +} + +impl ToOutbound { + fn v1_to_v2(self) -> Result { + match self { + Self::V1(x) => Ok(Self::V2(v1_to_v2::convert_to_outbound_v1_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v1(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V1(v2_to_v1::convert_to_outbound_v2_to_v1(x)?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v3(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V3(v2_to_v3::convert_to_outbound_v2_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v2(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V2(v3_to_v2::convert_to_outbound_v3_to_v2(x)?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v4(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V4(v3_to_v4::convert_to_outbound_v3_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v3(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V3(v4_to_v3::convert_to_outbound_v4_to_v3(x)?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v5(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V5(v4_to_v5::convert_to_outbound_v4_to_v5(x)?)), + _ => bail!("unexpected version"), + } + } + fn v5_to_v4(self) -> Result { + match self { + Self::V5(x) => Ok(Self::V4(v5_to_v4::convert_to_outbound_v5_to_v4(x)?)), + _ => bail!("unexpected version"), + } + } +} + +// MARK: ActorCommandKeyData + +pub enum ActorCommandKeyData { + V1(v1::ActorCommandKeyData), + V2(v2::ActorCommandKeyData), + V3(v3::ActorCommandKeyData), + V4(v4::ActorCommandKeyData), + V5(v5::ActorCommandKeyData), +} + +impl OwnedVersionedData for ActorCommandKeyData { + type Latest = v5::ActorCommandKeyData; + + fn wrap_latest(latest: Self::Latest) -> Self { + Self::V5(latest) + } + + fn unwrap_latest(self) -> Result { + match self { + Self::V5(x) => Ok(x), + _ => bail!("version not latest"), + } + } + + fn deserialize_version(payload: &[u8], version: u16) -> Result { + match version { + 1 => Ok(Self::V1(serde_bare::from_slice(payload)?)), + 2 => Ok(Self::V2(serde_bare::from_slice(payload)?)), + 3 => Ok(Self::V3(serde_bare::from_slice(payload)?)), + 4 => Ok(Self::V4(serde_bare::from_slice(payload)?)), + 5 => Ok(Self::V5(serde_bare::from_slice(payload)?)), + _ => bail!("invalid version: {version}"), + } + } + + fn serialize_version(self, _version: u16) -> Result> { + match self { + Self::V1(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V2(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V3(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V4(x) => serde_bare::to_vec(&x).map_err(Into::into), + Self::V5(x) => serde_bare::to_vec(&x).map_err(Into::into), + } + } + + fn deserialize_converters() -> Vec Result> { + vec![ + Self::v1_to_v2, + Self::v2_to_v3, + Self::v3_to_v4, + Self::v4_to_v5, + ] + } + + fn serialize_converters() -> Vec Result> { + vec![ + Self::v5_to_v4, + Self::v4_to_v3, + Self::v3_to_v2, + Self::v2_to_v1, + ] + } +} + +impl ActorCommandKeyData { + fn v1_to_v2(self) -> Result { + match self { + Self::V1(x) => Ok(Self::V2(v1_to_v2::convert_actor_command_key_data_v1_to_v2( + x, + )?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v1(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V1(v2_to_v1::convert_actor_command_key_data_v2_to_v1( + x, + )?)), + _ => bail!("unexpected version"), + } + } + fn v2_to_v3(self) -> Result { + match self { + Self::V2(x) => Ok(Self::V3(v2_to_v3::convert_actor_command_key_data_v2_to_v3( + x, + )?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v2(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V2(v3_to_v2::convert_actor_command_key_data_v3_to_v2( + x, + )?)), + _ => bail!("unexpected version"), + } + } + fn v3_to_v4(self) -> Result { + match self { + Self::V3(x) => Ok(Self::V4(v3_to_v4::convert_actor_command_key_data_v3_to_v4( + x, + )?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v3(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V3(v4_to_v3::convert_actor_command_key_data_v4_to_v3( + x, + )?)), + _ => bail!("unexpected version"), + } + } + fn v4_to_v5(self) -> Result { + match self { + Self::V4(x) => Ok(Self::V5(v4_to_v5::convert_actor_command_key_data_v4_to_v5( + x, + )?)), + _ => bail!("unexpected version"), + } + } + fn v5_to_v4(self) -> Result { + match self { + Self::V5(x) => Ok(Self::V4(v5_to_v4::convert_actor_command_key_data_v5_to_v4( + x, + )?)), + _ => bail!("unexpected version"), + } + } +} + +// MARK: Tests + +#[cfg(test)] +mod tests { + use anyhow::Result; + use vbare::OwnedVersionedData; + + use super::{ActorCommandKeyData, ToEnvoy}; + use crate::{ + PROTOCOL_VERSION, + generated::{v1, v2, v5}, + }; + + #[test] + fn protocol_version_constant_matches_schema_version() { + assert_eq!(PROTOCOL_VERSION, 5); + } + + #[test] + fn v1_start_command_deserializes_into_v3_without_sqlite_startup_data() -> Result<()> { + let payload = + serde_bare::to_vec(&v1::ToEnvoy::ToEnvoyCommands(vec![v1::CommandWrapper { + checkpoint: v1::ActorCheckpoint { + actor_id: "actor".into(), + generation: 7, + index: 3, + }, + inner: v1::Command::CommandStartActor(v1::CommandStartActor { + config: v1::ActorConfig { + name: "demo".into(), + key: Some("key".into()), + create_ts: 42, + input: None, + }, + hibernating_requests: Vec::new(), + preloaded_kv: None, + }), + }]))?; + + let decoded = ToEnvoy::deserialize(&payload, 1)?; + let v5::ToEnvoy::ToEnvoyCommands(commands) = decoded else { + panic!("expected commands"); + }; + let v5::Command::CommandStartActor(start) = &commands[0].inner else { + panic!("expected start actor"); + }; + + assert!(start.preloaded_kv.is_none()); + assert_eq!(commands[0].checkpoint.generation, 7); + + Ok(()) + } + + #[test] + fn v2_sqlite_response_does_not_deserialize_to_stateless_protocol() -> Result<()> { + let payload = serde_bare::to_vec(&v2::ToEnvoy::ToEnvoySqliteCommitResponse( + v2::ToEnvoySqliteCommitResponse { + request_id: 1, + data: v2::SqliteCommitResponse::SqliteErrorResponse(v2::SqliteErrorResponse { + message: "old sqlite".into(), + }), + }, + ))?; + + assert!(ToEnvoy::deserialize(&payload, 2).is_err()); + Ok(()) + } + + #[test] + fn actor_command_key_data_round_trips_to_v1() -> Result<()> { + let encoded = ActorCommandKeyData::wrap_latest(v5::ActorCommandKeyData::CommandStartActor( + v5::CommandStartActor { + config: v5::ActorConfig { + name: "demo".into(), + key: None, + create_ts: 7, + input: None, + }, + hibernating_requests: Vec::new(), + preloaded_kv: None, + }, + )) + .serialize(1)?; + + let decoded = ActorCommandKeyData::deserialize(&encoded, 1)?; + let v5::ActorCommandKeyData::CommandStartActor(start) = decoded else { + panic!("expected start actor"); + }; + assert_eq!(start.config.name, "demo"); + + Ok(()) + } +} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned/v1_to_v2.rs b/engine/sdks/rust/envoy-protocol/src/versioned/v1_to_v2.rs new file mode 100644 index 0000000000..6eea13118e --- /dev/null +++ b/engine/sdks/rust/envoy-protocol/src/versioned/v1_to_v2.rs @@ -0,0 +1,740 @@ +// @generated initial scaffold by scripts/vbare-gen-converters +// from: v1.bare, to: v2.bare +// Replace each todo!() with the migration semantics, then drop the @generated marker. + +#![allow(dead_code, unused_variables)] + +use anyhow::Result; + +use crate::generated::{v1, v2}; + +pub fn convert_kv_metadata_v1_to_v2(x: v1::KvMetadata) -> Result { + Ok(v2::KvMetadata { + version: x.version, + update_ts: x.update_ts, + }) +} + +pub fn convert_kv_list_range_query_v1_to_v2( + x: v1::KvListRangeQuery, +) -> Result { + Ok(v2::KvListRangeQuery { + start: x.start, + end: x.end, + exclusive: x.exclusive, + }) +} + +pub fn convert_kv_list_prefix_query_v1_to_v2( + x: v1::KvListPrefixQuery, +) -> Result { + Ok(v2::KvListPrefixQuery { key: x.key }) +} + +pub fn convert_kv_list_query_v1_to_v2(x: v1::KvListQuery) -> Result { + Ok(match x { + v1::KvListQuery::KvListAllQuery => v2::KvListQuery::KvListAllQuery, + v1::KvListQuery::KvListRangeQuery(v) => { + v2::KvListQuery::KvListRangeQuery(convert_kv_list_range_query_v1_to_v2(v)?) + } + v1::KvListQuery::KvListPrefixQuery(v) => { + v2::KvListQuery::KvListPrefixQuery(convert_kv_list_prefix_query_v1_to_v2(v)?) + } + }) +} + +pub fn convert_kv_get_request_v1_to_v2(x: v1::KvGetRequest) -> Result { + Ok(v2::KvGetRequest { keys: x.keys }) +} + +pub fn convert_kv_list_request_v1_to_v2(x: v1::KvListRequest) -> Result { + Ok(v2::KvListRequest { + query: convert_kv_list_query_v1_to_v2(x.query)?, + reverse: x.reverse, + limit: x.limit, + }) +} + +pub fn convert_kv_put_request_v1_to_v2(x: v1::KvPutRequest) -> Result { + Ok(v2::KvPutRequest { + keys: x.keys, + values: x.values, + }) +} + +pub fn convert_kv_delete_request_v1_to_v2(x: v1::KvDeleteRequest) -> Result { + Ok(v2::KvDeleteRequest { keys: x.keys }) +} + +pub fn convert_kv_delete_range_request_v1_to_v2( + x: v1::KvDeleteRangeRequest, +) -> Result { + Ok(v2::KvDeleteRangeRequest { + start: x.start, + end: x.end, + }) +} + +pub fn convert_kv_error_response_v1_to_v2(x: v1::KvErrorResponse) -> Result { + Ok(v2::KvErrorResponse { message: x.message }) +} + +pub fn convert_kv_get_response_v1_to_v2(x: v1::KvGetResponse) -> Result { + Ok(v2::KvGetResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v1_to_v2(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_list_response_v1_to_v2(x: v1::KvListResponse) -> Result { + Ok(v2::KvListResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v1_to_v2(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_request_data_v1_to_v2(x: v1::KvRequestData) -> Result { + Ok(match x { + v1::KvRequestData::KvGetRequest(v) => { + v2::KvRequestData::KvGetRequest(convert_kv_get_request_v1_to_v2(v)?) + } + v1::KvRequestData::KvListRequest(v) => { + v2::KvRequestData::KvListRequest(convert_kv_list_request_v1_to_v2(v)?) + } + v1::KvRequestData::KvPutRequest(v) => { + v2::KvRequestData::KvPutRequest(convert_kv_put_request_v1_to_v2(v)?) + } + v1::KvRequestData::KvDeleteRequest(v) => { + v2::KvRequestData::KvDeleteRequest(convert_kv_delete_request_v1_to_v2(v)?) + } + v1::KvRequestData::KvDeleteRangeRequest(v) => { + v2::KvRequestData::KvDeleteRangeRequest(convert_kv_delete_range_request_v1_to_v2(v)?) + } + v1::KvRequestData::KvDropRequest => v2::KvRequestData::KvDropRequest, + }) +} + +pub fn convert_kv_response_data_v1_to_v2(x: v1::KvResponseData) -> Result { + Ok(match x { + v1::KvResponseData::KvErrorResponse(v) => { + v2::KvResponseData::KvErrorResponse(convert_kv_error_response_v1_to_v2(v)?) + } + v1::KvResponseData::KvGetResponse(v) => { + v2::KvResponseData::KvGetResponse(convert_kv_get_response_v1_to_v2(v)?) + } + v1::KvResponseData::KvListResponse(v) => { + v2::KvResponseData::KvListResponse(convert_kv_list_response_v1_to_v2(v)?) + } + v1::KvResponseData::KvPutResponse => v2::KvResponseData::KvPutResponse, + v1::KvResponseData::KvDeleteResponse => v2::KvResponseData::KvDeleteResponse, + v1::KvResponseData::KvDropResponse => v2::KvResponseData::KvDropResponse, + }) +} + +pub fn convert_stop_code_v1_to_v2(x: v1::StopCode) -> Result { + Ok(match x { + v1::StopCode::Ok => v2::StopCode::Ok, + v1::StopCode::Error => v2::StopCode::Error, + }) +} + +pub fn convert_actor_name_v1_to_v2(x: v1::ActorName) -> Result { + Ok(v2::ActorName { + metadata: x.metadata, + }) +} + +pub fn convert_actor_config_v1_to_v2(x: v1::ActorConfig) -> Result { + Ok(v2::ActorConfig { + name: x.name, + key: x.key, + create_ts: x.create_ts, + input: x.input, + }) +} + +pub fn convert_actor_checkpoint_v1_to_v2(x: v1::ActorCheckpoint) -> Result { + Ok(v2::ActorCheckpoint { + actor_id: x.actor_id, + generation: x.generation, + index: x.index, + }) +} + +pub fn convert_actor_intent_v1_to_v2(x: v1::ActorIntent) -> Result { + Ok(match x { + v1::ActorIntent::ActorIntentSleep => v2::ActorIntent::ActorIntentSleep, + v1::ActorIntent::ActorIntentStop => v2::ActorIntent::ActorIntentStop, + }) +} + +pub fn convert_actor_state_stopped_v1_to_v2( + x: v1::ActorStateStopped, +) -> Result { + Ok(v2::ActorStateStopped { + code: convert_stop_code_v1_to_v2(x.code)?, + message: x.message, + }) +} + +pub fn convert_actor_state_v1_to_v2(x: v1::ActorState) -> Result { + Ok(match x { + v1::ActorState::ActorStateRunning => v2::ActorState::ActorStateRunning, + v1::ActorState::ActorStateStopped(v) => { + v2::ActorState::ActorStateStopped(convert_actor_state_stopped_v1_to_v2(v)?) + } + }) +} + +pub fn convert_event_actor_intent_v1_to_v2( + x: v1::EventActorIntent, +) -> Result { + Ok(v2::EventActorIntent { + intent: convert_actor_intent_v1_to_v2(x.intent)?, + }) +} + +pub fn convert_event_actor_state_update_v1_to_v2( + x: v1::EventActorStateUpdate, +) -> Result { + Ok(v2::EventActorStateUpdate { + state: convert_actor_state_v1_to_v2(x.state)?, + }) +} + +pub fn convert_event_actor_set_alarm_v1_to_v2( + x: v1::EventActorSetAlarm, +) -> Result { + Ok(v2::EventActorSetAlarm { + alarm_ts: x.alarm_ts, + }) +} + +pub fn convert_event_v1_to_v2(x: v1::Event) -> Result { + Ok(match x { + v1::Event::EventActorIntent(v) => { + v2::Event::EventActorIntent(convert_event_actor_intent_v1_to_v2(v)?) + } + v1::Event::EventActorStateUpdate(v) => { + v2::Event::EventActorStateUpdate(convert_event_actor_state_update_v1_to_v2(v)?) + } + v1::Event::EventActorSetAlarm(v) => { + v2::Event::EventActorSetAlarm(convert_event_actor_set_alarm_v1_to_v2(v)?) + } + }) +} + +pub fn convert_event_wrapper_v1_to_v2(x: v1::EventWrapper) -> Result { + Ok(v2::EventWrapper { + checkpoint: convert_actor_checkpoint_v1_to_v2(x.checkpoint)?, + inner: convert_event_v1_to_v2(x.inner)?, + }) +} + +pub fn convert_preloaded_kv_entry_v1_to_v2( + x: v1::PreloadedKvEntry, +) -> Result { + Ok(v2::PreloadedKvEntry { + key: x.key, + value: x.value, + metadata: convert_kv_metadata_v1_to_v2(x.metadata)?, + }) +} + +pub fn convert_preloaded_kv_v1_to_v2(x: v1::PreloadedKv) -> Result { + Ok(v2::PreloadedKv { + entries: x + .entries + .into_iter() + .map(|v| convert_preloaded_kv_entry_v1_to_v2(v)) + .collect::>>()?, + requested_get_keys: x.requested_get_keys, + requested_prefixes: x.requested_prefixes, + }) +} + +pub fn convert_hibernating_request_v1_to_v2( + x: v1::HibernatingRequest, +) -> Result { + Ok(v2::HibernatingRequest { + gateway_id: x.gateway_id, + request_id: x.request_id, + }) +} + +pub fn convert_command_start_actor_v1_to_v2( + x: v1::CommandStartActor, +) -> Result { + Ok(v2::CommandStartActor { + config: convert_actor_config_v1_to_v2(x.config)?, + hibernating_requests: x + .hibernating_requests + .into_iter() + .map(|v| convert_hibernating_request_v1_to_v2(v)) + .collect::>>()?, + preloaded_kv: x + .preloaded_kv + .map(|v| convert_preloaded_kv_v1_to_v2(v)) + .transpose()?, + // v1 had no SQLite startup data; v2 added the field as optional. + sqlite_startup_data: None, + }) +} + +pub fn convert_stop_actor_reason_v1_to_v2(x: v1::StopActorReason) -> Result { + Ok(match x { + v1::StopActorReason::SleepIntent => v2::StopActorReason::SleepIntent, + v1::StopActorReason::StopIntent => v2::StopActorReason::StopIntent, + v1::StopActorReason::Destroy => v2::StopActorReason::Destroy, + v1::StopActorReason::GoingAway => v2::StopActorReason::GoingAway, + v1::StopActorReason::Lost => v2::StopActorReason::Lost, + }) +} + +pub fn convert_command_stop_actor_v1_to_v2( + x: v1::CommandStopActor, +) -> Result { + Ok(v2::CommandStopActor { + reason: convert_stop_actor_reason_v1_to_v2(x.reason)?, + }) +} + +pub fn convert_command_v1_to_v2(x: v1::Command) -> Result { + Ok(match x { + v1::Command::CommandStartActor(v) => { + v2::Command::CommandStartActor(convert_command_start_actor_v1_to_v2(v)?) + } + v1::Command::CommandStopActor(v) => { + v2::Command::CommandStopActor(convert_command_stop_actor_v1_to_v2(v)?) + } + }) +} + +pub fn convert_command_wrapper_v1_to_v2(x: v1::CommandWrapper) -> Result { + Ok(v2::CommandWrapper { + checkpoint: convert_actor_checkpoint_v1_to_v2(x.checkpoint)?, + inner: convert_command_v1_to_v2(x.inner)?, + }) +} + +pub fn convert_actor_command_key_data_v1_to_v2( + x: v1::ActorCommandKeyData, +) -> Result { + Ok(match x { + v1::ActorCommandKeyData::CommandStartActor(v) => { + v2::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v1_to_v2(v)?) + } + v1::ActorCommandKeyData::CommandStopActor(v) => { + v2::ActorCommandKeyData::CommandStopActor(convert_command_stop_actor_v1_to_v2(v)?) + } + }) +} + +pub fn convert_message_id_v1_to_v2(x: v1::MessageId) -> Result { + Ok(v2::MessageId { + gateway_id: x.gateway_id, + request_id: x.request_id, + message_index: x.message_index, + }) +} + +pub fn convert_to_envoy_request_start_v1_to_v2( + x: v1::ToEnvoyRequestStart, +) -> Result { + Ok(v2::ToEnvoyRequestStart { + actor_id: x.actor_id, + method: x.method, + path: x.path, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_envoy_request_chunk_v1_to_v2( + x: v1::ToEnvoyRequestChunk, +) -> Result { + Ok(v2::ToEnvoyRequestChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_rivet_response_start_v1_to_v2( + x: v1::ToRivetResponseStart, +) -> Result { + Ok(v2::ToRivetResponseStart { + status: x.status, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_rivet_response_chunk_v1_to_v2( + x: v1::ToRivetResponseChunk, +) -> Result { + Ok(v2::ToRivetResponseChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_envoy_web_socket_open_v1_to_v2( + x: v1::ToEnvoyWebSocketOpen, +) -> Result { + Ok(v2::ToEnvoyWebSocketOpen { + actor_id: x.actor_id, + path: x.path, + headers: x.headers, + }) +} + +pub fn convert_to_envoy_web_socket_message_v1_to_v2( + x: v1::ToEnvoyWebSocketMessage, +) -> Result { + Ok(v2::ToEnvoyWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_envoy_web_socket_close_v1_to_v2( + x: v1::ToEnvoyWebSocketClose, +) -> Result { + Ok(v2::ToEnvoyWebSocketClose { + code: x.code, + reason: x.reason, + }) +} + +pub fn convert_to_rivet_web_socket_open_v1_to_v2( + x: v1::ToRivetWebSocketOpen, +) -> Result { + Ok(v2::ToRivetWebSocketOpen { + can_hibernate: x.can_hibernate, + }) +} + +pub fn convert_to_rivet_web_socket_message_v1_to_v2( + x: v1::ToRivetWebSocketMessage, +) -> Result { + Ok(v2::ToRivetWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_rivet_web_socket_message_ack_v1_to_v2( + x: v1::ToRivetWebSocketMessageAck, +) -> Result { + Ok(v2::ToRivetWebSocketMessageAck { index: x.index }) +} + +pub fn convert_to_rivet_web_socket_close_v1_to_v2( + x: v1::ToRivetWebSocketClose, +) -> Result { + Ok(v2::ToRivetWebSocketClose { + code: x.code, + reason: x.reason, + hibernate: x.hibernate, + }) +} + +pub fn convert_to_rivet_tunnel_message_kind_v1_to_v2( + x: v1::ToRivetTunnelMessageKind, +) -> Result { + Ok(match x { + v1::ToRivetTunnelMessageKind::ToRivetResponseStart(v) => { + v2::ToRivetTunnelMessageKind::ToRivetResponseStart( + convert_to_rivet_response_start_v1_to_v2(v)?, + ) + } + v1::ToRivetTunnelMessageKind::ToRivetResponseChunk(v) => { + v2::ToRivetTunnelMessageKind::ToRivetResponseChunk( + convert_to_rivet_response_chunk_v1_to_v2(v)?, + ) + } + v1::ToRivetTunnelMessageKind::ToRivetResponseAbort => { + v2::ToRivetTunnelMessageKind::ToRivetResponseAbort + } + v1::ToRivetTunnelMessageKind::ToRivetWebSocketOpen(v) => { + v2::ToRivetTunnelMessageKind::ToRivetWebSocketOpen( + convert_to_rivet_web_socket_open_v1_to_v2(v)?, + ) + } + v1::ToRivetTunnelMessageKind::ToRivetWebSocketMessage(v) => { + v2::ToRivetTunnelMessageKind::ToRivetWebSocketMessage( + convert_to_rivet_web_socket_message_v1_to_v2(v)?, + ) + } + v1::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck(v) => { + v2::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck( + convert_to_rivet_web_socket_message_ack_v1_to_v2(v)?, + ) + } + v1::ToRivetTunnelMessageKind::ToRivetWebSocketClose(v) => { + v2::ToRivetTunnelMessageKind::ToRivetWebSocketClose( + convert_to_rivet_web_socket_close_v1_to_v2(v)?, + ) + } + }) +} + +pub fn convert_to_rivet_tunnel_message_v1_to_v2( + x: v1::ToRivetTunnelMessage, +) -> Result { + Ok(v2::ToRivetTunnelMessage { + message_id: convert_message_id_v1_to_v2(x.message_id)?, + message_kind: convert_to_rivet_tunnel_message_kind_v1_to_v2(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_tunnel_message_kind_v1_to_v2( + x: v1::ToEnvoyTunnelMessageKind, +) -> Result { + Ok(match x { + v1::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart( + convert_to_envoy_request_start_v1_to_v2(v)?, + ) + } + v1::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk( + convert_to_envoy_request_chunk_v1_to_v2(v)?, + ) + } + v1::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort + } + v1::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen( + convert_to_envoy_web_socket_open_v1_to_v2(v)?, + ) + } + v1::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage( + convert_to_envoy_web_socket_message_v1_to_v2(v)?, + ) + } + v1::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose( + convert_to_envoy_web_socket_close_v1_to_v2(v)?, + ) + } + }) +} + +pub fn convert_to_envoy_tunnel_message_v1_to_v2( + x: v1::ToEnvoyTunnelMessage, +) -> Result { + Ok(v2::ToEnvoyTunnelMessage { + message_id: convert_message_id_v1_to_v2(x.message_id)?, + message_kind: convert_to_envoy_tunnel_message_kind_v1_to_v2(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_ping_v1_to_v2(x: v1::ToEnvoyPing) -> Result { + Ok(v2::ToEnvoyPing { ts: x.ts }) +} + +pub fn convert_to_rivet_metadata_v1_to_v2(x: v1::ToRivetMetadata) -> Result { + Ok(v2::ToRivetMetadata { + prepopulate_actor_names: x + .prepopulate_actor_names + .map(|v| { + v.into_iter() + .map(|(k, v)| -> Result<_> { Ok((k, convert_actor_name_v1_to_v2(v)?)) }) + .collect::>() + }) + .transpose()?, + metadata: x.metadata, + }) +} + +pub fn convert_to_rivet_events_v1_to_v2(x: v1::ToRivetEvents) -> Result { + Ok(x.into_iter() + .map(|v| convert_event_wrapper_v1_to_v2(v)) + .collect::>>()?) +} + +pub fn convert_to_rivet_ack_commands_v1_to_v2( + x: v1::ToRivetAckCommands, +) -> Result { + Ok(v2::ToRivetAckCommands { + last_command_checkpoints: x + .last_command_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v1_to_v2(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_rivet_pong_v1_to_v2(x: v1::ToRivetPong) -> Result { + Ok(v2::ToRivetPong { ts: x.ts }) +} + +pub fn convert_to_rivet_kv_request_v1_to_v2( + x: v1::ToRivetKvRequest, +) -> Result { + Ok(v2::ToRivetKvRequest { + actor_id: x.actor_id, + request_id: x.request_id, + data: convert_kv_request_data_v1_to_v2(x.data)?, + }) +} + +pub fn convert_to_rivet_v1_to_v2(x: v1::ToRivet) -> Result { + Ok(match x { + v1::ToRivet::ToRivetMetadata(v) => { + v2::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v1_to_v2(v)?) + } + v1::ToRivet::ToRivetEvents(v) => { + v2::ToRivet::ToRivetEvents(convert_to_rivet_events_v1_to_v2(v)?) + } + v1::ToRivet::ToRivetAckCommands(v) => { + v2::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v1_to_v2(v)?) + } + v1::ToRivet::ToRivetStopping => v2::ToRivet::ToRivetStopping, + v1::ToRivet::ToRivetPong(v) => v2::ToRivet::ToRivetPong(convert_to_rivet_pong_v1_to_v2(v)?), + v1::ToRivet::ToRivetKvRequest(v) => { + v2::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v1_to_v2(v)?) + } + v1::ToRivet::ToRivetTunnelMessage(v) => { + v2::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v1_to_v2(v)?) + } + }) +} + +pub fn convert_protocol_metadata_v1_to_v2(x: v1::ProtocolMetadata) -> Result { + Ok(v2::ProtocolMetadata { + envoy_lost_threshold: x.envoy_lost_threshold, + actor_stop_threshold: x.actor_stop_threshold, + max_response_payload_size: x.max_response_payload_size, + }) +} + +pub fn convert_to_envoy_init_v1_to_v2(x: v1::ToEnvoyInit) -> Result { + Ok(v2::ToEnvoyInit { + metadata: convert_protocol_metadata_v1_to_v2(x.metadata)?, + }) +} + +pub fn convert_to_envoy_commands_v1_to_v2(x: v1::ToEnvoyCommands) -> Result { + Ok(x.into_iter() + .map(|v| convert_command_wrapper_v1_to_v2(v)) + .collect::>>()?) +} + +pub fn convert_to_envoy_ack_events_v1_to_v2( + x: v1::ToEnvoyAckEvents, +) -> Result { + Ok(v2::ToEnvoyAckEvents { + last_event_checkpoints: x + .last_event_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v1_to_v2(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_envoy_kv_response_v1_to_v2( + x: v1::ToEnvoyKvResponse, +) -> Result { + Ok(v2::ToEnvoyKvResponse { + request_id: x.request_id, + data: convert_kv_response_data_v1_to_v2(x.data)?, + }) +} + +pub fn convert_to_envoy_v1_to_v2(x: v1::ToEnvoy) -> Result { + Ok(match x { + v1::ToEnvoy::ToEnvoyInit(v) => v2::ToEnvoy::ToEnvoyInit(convert_to_envoy_init_v1_to_v2(v)?), + v1::ToEnvoy::ToEnvoyCommands(v) => { + v2::ToEnvoy::ToEnvoyCommands(convert_to_envoy_commands_v1_to_v2(v)?) + } + v1::ToEnvoy::ToEnvoyAckEvents(v) => { + v2::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v1_to_v2(v)?) + } + v1::ToEnvoy::ToEnvoyKvResponse(v) => { + v2::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v1_to_v2(v)?) + } + v1::ToEnvoy::ToEnvoyTunnelMessage(v) => { + v2::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v1_to_v2(v)?) + } + v1::ToEnvoy::ToEnvoyPing(v) => v2::ToEnvoy::ToEnvoyPing(convert_to_envoy_ping_v1_to_v2(v)?), + }) +} + +pub fn convert_to_envoy_conn_ping_v1_to_v2(x: v1::ToEnvoyConnPing) -> Result { + Ok(v2::ToEnvoyConnPing { + gateway_id: x.gateway_id, + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_envoy_conn_v1_to_v2(x: v1::ToEnvoyConn) -> Result { + Ok(match x { + v1::ToEnvoyConn::ToEnvoyConnPing(v) => { + v2::ToEnvoyConn::ToEnvoyConnPing(convert_to_envoy_conn_ping_v1_to_v2(v)?) + } + v1::ToEnvoyConn::ToEnvoyConnClose => v2::ToEnvoyConn::ToEnvoyConnClose, + v1::ToEnvoyConn::ToEnvoyCommands(v) => { + v2::ToEnvoyConn::ToEnvoyCommands(convert_to_envoy_commands_v1_to_v2(v)?) + } + v1::ToEnvoyConn::ToEnvoyAckEvents(v) => { + v2::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v1_to_v2(v)?) + } + v1::ToEnvoyConn::ToEnvoyTunnelMessage(v) => { + v2::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v1_to_v2(v)?) + } + }) +} + +pub fn convert_to_gateway_pong_v1_to_v2(x: v1::ToGatewayPong) -> Result { + Ok(v2::ToGatewayPong { + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_gateway_v1_to_v2(x: v1::ToGateway) -> Result { + Ok(match x { + v1::ToGateway::ToGatewayPong(v) => { + v2::ToGateway::ToGatewayPong(convert_to_gateway_pong_v1_to_v2(v)?) + } + v1::ToGateway::ToRivetTunnelMessage(v) => { + v2::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v1_to_v2(v)?) + } + }) +} + +pub fn convert_to_outbound_actor_start_v1_to_v2( + x: v1::ToOutboundActorStart, +) -> Result { + Ok(v2::ToOutboundActorStart { + namespace_id: x.namespace_id, + pool_name: x.pool_name, + checkpoint: convert_actor_checkpoint_v1_to_v2(x.checkpoint)?, + actor_config: convert_actor_config_v1_to_v2(x.actor_config)?, + }) +} + +pub fn convert_to_outbound_v1_to_v2(x: v1::ToOutbound) -> Result { + Ok(match x { + v1::ToOutbound::ToOutboundActorStart(v) => { + v2::ToOutbound::ToOutboundActorStart(convert_to_outbound_actor_start_v1_to_v2(v)?) + } + }) +} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned/v2_to_v1.rs b/engine/sdks/rust/envoy-protocol/src/versioned/v2_to_v1.rs new file mode 100644 index 0000000000..740aee3c69 --- /dev/null +++ b/engine/sdks/rust/envoy-protocol/src/versioned/v2_to_v1.rs @@ -0,0 +1,763 @@ +// @generated initial scaffold by scripts/vbare-gen-converters +// from: v2.bare, to: v1.bare +// Replace each todo!() with the migration semantics, then drop the @generated marker. + +#![allow(dead_code, unused_variables)] + +use anyhow::{Result, bail}; + +use crate::generated::{v1, v2}; +use crate::versioned::{ + ProtocolCompatibilityDirection, ProtocolCompatibilityFeature, incompatible, +}; + +pub fn convert_kv_metadata_v2_to_v1(x: v2::KvMetadata) -> Result { + Ok(v1::KvMetadata { + version: x.version, + update_ts: x.update_ts, + }) +} + +pub fn convert_kv_list_range_query_v2_to_v1( + x: v2::KvListRangeQuery, +) -> Result { + Ok(v1::KvListRangeQuery { + start: x.start, + end: x.end, + exclusive: x.exclusive, + }) +} + +pub fn convert_kv_list_prefix_query_v2_to_v1( + x: v2::KvListPrefixQuery, +) -> Result { + Ok(v1::KvListPrefixQuery { key: x.key }) +} + +pub fn convert_kv_list_query_v2_to_v1(x: v2::KvListQuery) -> Result { + Ok(match x { + v2::KvListQuery::KvListAllQuery => v1::KvListQuery::KvListAllQuery, + v2::KvListQuery::KvListRangeQuery(v) => { + v1::KvListQuery::KvListRangeQuery(convert_kv_list_range_query_v2_to_v1(v)?) + } + v2::KvListQuery::KvListPrefixQuery(v) => { + v1::KvListQuery::KvListPrefixQuery(convert_kv_list_prefix_query_v2_to_v1(v)?) + } + }) +} + +pub fn convert_kv_get_request_v2_to_v1(x: v2::KvGetRequest) -> Result { + Ok(v1::KvGetRequest { keys: x.keys }) +} + +pub fn convert_kv_list_request_v2_to_v1(x: v2::KvListRequest) -> Result { + Ok(v1::KvListRequest { + query: convert_kv_list_query_v2_to_v1(x.query)?, + reverse: x.reverse, + limit: x.limit, + }) +} + +pub fn convert_kv_put_request_v2_to_v1(x: v2::KvPutRequest) -> Result { + Ok(v1::KvPutRequest { + keys: x.keys, + values: x.values, + }) +} + +pub fn convert_kv_delete_request_v2_to_v1(x: v2::KvDeleteRequest) -> Result { + Ok(v1::KvDeleteRequest { keys: x.keys }) +} + +pub fn convert_kv_delete_range_request_v2_to_v1( + x: v2::KvDeleteRangeRequest, +) -> Result { + Ok(v1::KvDeleteRangeRequest { + start: x.start, + end: x.end, + }) +} + +pub fn convert_kv_error_response_v2_to_v1(x: v2::KvErrorResponse) -> Result { + Ok(v1::KvErrorResponse { message: x.message }) +} + +pub fn convert_kv_get_response_v2_to_v1(x: v2::KvGetResponse) -> Result { + Ok(v1::KvGetResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v2_to_v1(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_list_response_v2_to_v1(x: v2::KvListResponse) -> Result { + Ok(v1::KvListResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v2_to_v1(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_request_data_v2_to_v1(x: v2::KvRequestData) -> Result { + Ok(match x { + v2::KvRequestData::KvGetRequest(v) => { + v1::KvRequestData::KvGetRequest(convert_kv_get_request_v2_to_v1(v)?) + } + v2::KvRequestData::KvListRequest(v) => { + v1::KvRequestData::KvListRequest(convert_kv_list_request_v2_to_v1(v)?) + } + v2::KvRequestData::KvPutRequest(v) => { + v1::KvRequestData::KvPutRequest(convert_kv_put_request_v2_to_v1(v)?) + } + v2::KvRequestData::KvDeleteRequest(v) => { + v1::KvRequestData::KvDeleteRequest(convert_kv_delete_request_v2_to_v1(v)?) + } + v2::KvRequestData::KvDeleteRangeRequest(v) => { + v1::KvRequestData::KvDeleteRangeRequest(convert_kv_delete_range_request_v2_to_v1(v)?) + } + v2::KvRequestData::KvDropRequest => v1::KvRequestData::KvDropRequest, + }) +} + +pub fn convert_kv_response_data_v2_to_v1(x: v2::KvResponseData) -> Result { + Ok(match x { + v2::KvResponseData::KvErrorResponse(v) => { + v1::KvResponseData::KvErrorResponse(convert_kv_error_response_v2_to_v1(v)?) + } + v2::KvResponseData::KvGetResponse(v) => { + v1::KvResponseData::KvGetResponse(convert_kv_get_response_v2_to_v1(v)?) + } + v2::KvResponseData::KvListResponse(v) => { + v1::KvResponseData::KvListResponse(convert_kv_list_response_v2_to_v1(v)?) + } + v2::KvResponseData::KvPutResponse => v1::KvResponseData::KvPutResponse, + v2::KvResponseData::KvDeleteResponse => v1::KvResponseData::KvDeleteResponse, + v2::KvResponseData::KvDropResponse => v1::KvResponseData::KvDropResponse, + }) +} + +pub fn convert_stop_code_v2_to_v1(x: v2::StopCode) -> Result { + Ok(match x { + v2::StopCode::Ok => v1::StopCode::Ok, + v2::StopCode::Error => v1::StopCode::Error, + }) +} + +pub fn convert_actor_name_v2_to_v1(x: v2::ActorName) -> Result { + Ok(v1::ActorName { + metadata: x.metadata, + }) +} + +pub fn convert_actor_config_v2_to_v1(x: v2::ActorConfig) -> Result { + Ok(v1::ActorConfig { + name: x.name, + key: x.key, + create_ts: x.create_ts, + input: x.input, + }) +} + +pub fn convert_actor_checkpoint_v2_to_v1(x: v2::ActorCheckpoint) -> Result { + Ok(v1::ActorCheckpoint { + actor_id: x.actor_id, + generation: x.generation, + index: x.index, + }) +} + +pub fn convert_actor_intent_v2_to_v1(x: v2::ActorIntent) -> Result { + Ok(match x { + v2::ActorIntent::ActorIntentSleep => v1::ActorIntent::ActorIntentSleep, + v2::ActorIntent::ActorIntentStop => v1::ActorIntent::ActorIntentStop, + }) +} + +pub fn convert_actor_state_stopped_v2_to_v1( + x: v2::ActorStateStopped, +) -> Result { + Ok(v1::ActorStateStopped { + code: convert_stop_code_v2_to_v1(x.code)?, + message: x.message, + }) +} + +pub fn convert_actor_state_v2_to_v1(x: v2::ActorState) -> Result { + Ok(match x { + v2::ActorState::ActorStateRunning => v1::ActorState::ActorStateRunning, + v2::ActorState::ActorStateStopped(v) => { + v1::ActorState::ActorStateStopped(convert_actor_state_stopped_v2_to_v1(v)?) + } + }) +} + +pub fn convert_event_actor_intent_v2_to_v1( + x: v2::EventActorIntent, +) -> Result { + Ok(v1::EventActorIntent { + intent: convert_actor_intent_v2_to_v1(x.intent)?, + }) +} + +pub fn convert_event_actor_state_update_v2_to_v1( + x: v2::EventActorStateUpdate, +) -> Result { + Ok(v1::EventActorStateUpdate { + state: convert_actor_state_v2_to_v1(x.state)?, + }) +} + +pub fn convert_event_actor_set_alarm_v2_to_v1( + x: v2::EventActorSetAlarm, +) -> Result { + Ok(v1::EventActorSetAlarm { + alarm_ts: x.alarm_ts, + }) +} + +pub fn convert_event_v2_to_v1(x: v2::Event) -> Result { + Ok(match x { + v2::Event::EventActorIntent(v) => { + v1::Event::EventActorIntent(convert_event_actor_intent_v2_to_v1(v)?) + } + v2::Event::EventActorStateUpdate(v) => { + v1::Event::EventActorStateUpdate(convert_event_actor_state_update_v2_to_v1(v)?) + } + v2::Event::EventActorSetAlarm(v) => { + v1::Event::EventActorSetAlarm(convert_event_actor_set_alarm_v2_to_v1(v)?) + } + }) +} + +pub fn convert_event_wrapper_v2_to_v1(x: v2::EventWrapper) -> Result { + Ok(v1::EventWrapper { + checkpoint: convert_actor_checkpoint_v2_to_v1(x.checkpoint)?, + inner: convert_event_v2_to_v1(x.inner)?, + }) +} + +pub fn convert_preloaded_kv_entry_v2_to_v1( + x: v2::PreloadedKvEntry, +) -> Result { + Ok(v1::PreloadedKvEntry { + key: x.key, + value: x.value, + metadata: convert_kv_metadata_v2_to_v1(x.metadata)?, + }) +} + +pub fn convert_preloaded_kv_v2_to_v1(x: v2::PreloadedKv) -> Result { + Ok(v1::PreloadedKv { + entries: x + .entries + .into_iter() + .map(|v| convert_preloaded_kv_entry_v2_to_v1(v)) + .collect::>>()?, + requested_get_keys: x.requested_get_keys, + requested_prefixes: x.requested_prefixes, + }) +} + +pub fn convert_hibernating_request_v2_to_v1( + x: v2::HibernatingRequest, +) -> Result { + Ok(v1::HibernatingRequest { + gateway_id: x.gateway_id, + request_id: x.request_id, + }) +} + +pub fn convert_command_start_actor_v2_to_v1( + x: v2::CommandStartActor, +) -> Result { + if x.sqlite_startup_data.is_some() { + return Err(incompatible( + ProtocolCompatibilityFeature::SqliteStartupData, + ProtocolCompatibilityDirection::ToEnvoy, + 2, + 1, + )); + } + Ok(v1::CommandStartActor { + config: convert_actor_config_v2_to_v1(x.config)?, + hibernating_requests: x + .hibernating_requests + .into_iter() + .map(|v| convert_hibernating_request_v2_to_v1(v)) + .collect::>>()?, + preloaded_kv: x + .preloaded_kv + .map(|v| convert_preloaded_kv_v2_to_v1(v)) + .transpose()?, + }) +} + +pub fn convert_stop_actor_reason_v2_to_v1(x: v2::StopActorReason) -> Result { + Ok(match x { + v2::StopActorReason::SleepIntent => v1::StopActorReason::SleepIntent, + v2::StopActorReason::StopIntent => v1::StopActorReason::StopIntent, + v2::StopActorReason::Destroy => v1::StopActorReason::Destroy, + v2::StopActorReason::GoingAway => v1::StopActorReason::GoingAway, + v2::StopActorReason::Lost => v1::StopActorReason::Lost, + }) +} + +pub fn convert_command_stop_actor_v2_to_v1( + x: v2::CommandStopActor, +) -> Result { + Ok(v1::CommandStopActor { + reason: convert_stop_actor_reason_v2_to_v1(x.reason)?, + }) +} + +pub fn convert_command_v2_to_v1(x: v2::Command) -> Result { + Ok(match x { + v2::Command::CommandStartActor(v) => { + v1::Command::CommandStartActor(convert_command_start_actor_v2_to_v1(v)?) + } + v2::Command::CommandStopActor(v) => { + v1::Command::CommandStopActor(convert_command_stop_actor_v2_to_v1(v)?) + } + }) +} + +pub fn convert_command_wrapper_v2_to_v1(x: v2::CommandWrapper) -> Result { + Ok(v1::CommandWrapper { + checkpoint: convert_actor_checkpoint_v2_to_v1(x.checkpoint)?, + inner: convert_command_v2_to_v1(x.inner)?, + }) +} + +pub fn convert_actor_command_key_data_v2_to_v1( + x: v2::ActorCommandKeyData, +) -> Result { + Ok(match x { + v2::ActorCommandKeyData::CommandStartActor(v) => { + v1::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v2_to_v1(v)?) + } + v2::ActorCommandKeyData::CommandStopActor(v) => { + v1::ActorCommandKeyData::CommandStopActor(convert_command_stop_actor_v2_to_v1(v)?) + } + }) +} + +pub fn convert_message_id_v2_to_v1(x: v2::MessageId) -> Result { + Ok(v1::MessageId { + gateway_id: x.gateway_id, + request_id: x.request_id, + message_index: x.message_index, + }) +} + +pub fn convert_to_envoy_request_start_v2_to_v1( + x: v2::ToEnvoyRequestStart, +) -> Result { + Ok(v1::ToEnvoyRequestStart { + actor_id: x.actor_id, + method: x.method, + path: x.path, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_envoy_request_chunk_v2_to_v1( + x: v2::ToEnvoyRequestChunk, +) -> Result { + Ok(v1::ToEnvoyRequestChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_rivet_response_start_v2_to_v1( + x: v2::ToRivetResponseStart, +) -> Result { + Ok(v1::ToRivetResponseStart { + status: x.status, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_rivet_response_chunk_v2_to_v1( + x: v2::ToRivetResponseChunk, +) -> Result { + Ok(v1::ToRivetResponseChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_envoy_web_socket_open_v2_to_v1( + x: v2::ToEnvoyWebSocketOpen, +) -> Result { + Ok(v1::ToEnvoyWebSocketOpen { + actor_id: x.actor_id, + path: x.path, + headers: x.headers, + }) +} + +pub fn convert_to_envoy_web_socket_message_v2_to_v1( + x: v2::ToEnvoyWebSocketMessage, +) -> Result { + Ok(v1::ToEnvoyWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_envoy_web_socket_close_v2_to_v1( + x: v2::ToEnvoyWebSocketClose, +) -> Result { + Ok(v1::ToEnvoyWebSocketClose { + code: x.code, + reason: x.reason, + }) +} + +pub fn convert_to_rivet_web_socket_open_v2_to_v1( + x: v2::ToRivetWebSocketOpen, +) -> Result { + Ok(v1::ToRivetWebSocketOpen { + can_hibernate: x.can_hibernate, + }) +} + +pub fn convert_to_rivet_web_socket_message_v2_to_v1( + x: v2::ToRivetWebSocketMessage, +) -> Result { + Ok(v1::ToRivetWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_rivet_web_socket_message_ack_v2_to_v1( + x: v2::ToRivetWebSocketMessageAck, +) -> Result { + Ok(v1::ToRivetWebSocketMessageAck { index: x.index }) +} + +pub fn convert_to_rivet_web_socket_close_v2_to_v1( + x: v2::ToRivetWebSocketClose, +) -> Result { + Ok(v1::ToRivetWebSocketClose { + code: x.code, + reason: x.reason, + hibernate: x.hibernate, + }) +} + +pub fn convert_to_rivet_tunnel_message_kind_v2_to_v1( + x: v2::ToRivetTunnelMessageKind, +) -> Result { + Ok(match x { + v2::ToRivetTunnelMessageKind::ToRivetResponseStart(v) => { + v1::ToRivetTunnelMessageKind::ToRivetResponseStart( + convert_to_rivet_response_start_v2_to_v1(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetResponseChunk(v) => { + v1::ToRivetTunnelMessageKind::ToRivetResponseChunk( + convert_to_rivet_response_chunk_v2_to_v1(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetResponseAbort => { + v1::ToRivetTunnelMessageKind::ToRivetResponseAbort + } + v2::ToRivetTunnelMessageKind::ToRivetWebSocketOpen(v) => { + v1::ToRivetTunnelMessageKind::ToRivetWebSocketOpen( + convert_to_rivet_web_socket_open_v2_to_v1(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetWebSocketMessage(v) => { + v1::ToRivetTunnelMessageKind::ToRivetWebSocketMessage( + convert_to_rivet_web_socket_message_v2_to_v1(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck(v) => { + v1::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck( + convert_to_rivet_web_socket_message_ack_v2_to_v1(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetWebSocketClose(v) => { + v1::ToRivetTunnelMessageKind::ToRivetWebSocketClose( + convert_to_rivet_web_socket_close_v2_to_v1(v)?, + ) + } + }) +} + +pub fn convert_to_rivet_tunnel_message_v2_to_v1( + x: v2::ToRivetTunnelMessage, +) -> Result { + Ok(v1::ToRivetTunnelMessage { + message_id: convert_message_id_v2_to_v1(x.message_id)?, + message_kind: convert_to_rivet_tunnel_message_kind_v2_to_v1(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_tunnel_message_kind_v2_to_v1( + x: v2::ToEnvoyTunnelMessageKind, +) -> Result { + Ok(match x { + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart(v) => { + v1::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart( + convert_to_envoy_request_start_v2_to_v1(v)?, + ) + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk(v) => { + v1::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk( + convert_to_envoy_request_chunk_v2_to_v1(v)?, + ) + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort => { + v1::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen(v) => { + v1::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen( + convert_to_envoy_web_socket_open_v2_to_v1(v)?, + ) + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage(v) => { + v1::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage( + convert_to_envoy_web_socket_message_v2_to_v1(v)?, + ) + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose(v) => { + v1::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose( + convert_to_envoy_web_socket_close_v2_to_v1(v)?, + ) + } + }) +} + +pub fn convert_to_envoy_tunnel_message_v2_to_v1( + x: v2::ToEnvoyTunnelMessage, +) -> Result { + Ok(v1::ToEnvoyTunnelMessage { + message_id: convert_message_id_v2_to_v1(x.message_id)?, + message_kind: convert_to_envoy_tunnel_message_kind_v2_to_v1(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_ping_v2_to_v1(x: v2::ToEnvoyPing) -> Result { + Ok(v1::ToEnvoyPing { ts: x.ts }) +} + +pub fn convert_to_rivet_metadata_v2_to_v1(x: v2::ToRivetMetadata) -> Result { + Ok(v1::ToRivetMetadata { + prepopulate_actor_names: x + .prepopulate_actor_names + .map(|v| { + v.into_iter() + .map(|(k, v)| -> Result<_> { Ok((k, convert_actor_name_v2_to_v1(v)?)) }) + .collect::>() + }) + .transpose()?, + metadata: x.metadata, + }) +} + +pub fn convert_to_rivet_events_v2_to_v1(x: v2::ToRivetEvents) -> Result { + Ok(x.into_iter() + .map(|v| convert_event_wrapper_v2_to_v1(v)) + .collect::>>()?) +} + +pub fn convert_to_rivet_ack_commands_v2_to_v1( + x: v2::ToRivetAckCommands, +) -> Result { + Ok(v1::ToRivetAckCommands { + last_command_checkpoints: x + .last_command_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v2_to_v1(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_rivet_pong_v2_to_v1(x: v2::ToRivetPong) -> Result { + Ok(v1::ToRivetPong { ts: x.ts }) +} + +pub fn convert_to_rivet_kv_request_v2_to_v1( + x: v2::ToRivetKvRequest, +) -> Result { + Ok(v1::ToRivetKvRequest { + actor_id: x.actor_id, + request_id: x.request_id, + data: convert_kv_request_data_v2_to_v1(x.data)?, + }) +} + +pub fn convert_to_rivet_v2_to_v1(x: v2::ToRivet) -> Result { + Ok(match x { + v2::ToRivet::ToRivetMetadata(v) => { + v1::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v2_to_v1(v)?) + } + v2::ToRivet::ToRivetEvents(v) => { + v1::ToRivet::ToRivetEvents(convert_to_rivet_events_v2_to_v1(v)?) + } + v2::ToRivet::ToRivetAckCommands(v) => { + v1::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v2_to_v1(v)?) + } + v2::ToRivet::ToRivetStopping => v1::ToRivet::ToRivetStopping, + v2::ToRivet::ToRivetPong(v) => v1::ToRivet::ToRivetPong(convert_to_rivet_pong_v2_to_v1(v)?), + v2::ToRivet::ToRivetKvRequest(v) => { + v1::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v2_to_v1(v)?) + } + v2::ToRivet::ToRivetTunnelMessage(v) => { + v1::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v2_to_v1(v)?) + } + v2::ToRivet::ToRivetSqliteGetPagesRequest(_) + | v2::ToRivet::ToRivetSqliteCommitRequest(_) + | v2::ToRivet::ToRivetSqliteCommitStageBeginRequest(_) + | v2::ToRivet::ToRivetSqliteCommitStageRequest(_) + | v2::ToRivet::ToRivetSqliteCommitFinalizeRequest(_) => { + bail!("sqlite requests require envoy-protocol v2") + } + }) +} + +pub fn convert_protocol_metadata_v2_to_v1(x: v2::ProtocolMetadata) -> Result { + Ok(v1::ProtocolMetadata { + envoy_lost_threshold: x.envoy_lost_threshold, + actor_stop_threshold: x.actor_stop_threshold, + max_response_payload_size: x.max_response_payload_size, + }) +} + +pub fn convert_to_envoy_init_v2_to_v1(x: v2::ToEnvoyInit) -> Result { + Ok(v1::ToEnvoyInit { + metadata: convert_protocol_metadata_v2_to_v1(x.metadata)?, + }) +} + +pub fn convert_to_envoy_commands_v2_to_v1(x: v2::ToEnvoyCommands) -> Result { + Ok(x.into_iter() + .map(|v| convert_command_wrapper_v2_to_v1(v)) + .collect::>>()?) +} + +pub fn convert_to_envoy_ack_events_v2_to_v1( + x: v2::ToEnvoyAckEvents, +) -> Result { + Ok(v1::ToEnvoyAckEvents { + last_event_checkpoints: x + .last_event_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v2_to_v1(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_envoy_kv_response_v2_to_v1( + x: v2::ToEnvoyKvResponse, +) -> Result { + Ok(v1::ToEnvoyKvResponse { + request_id: x.request_id, + data: convert_kv_response_data_v2_to_v1(x.data)?, + }) +} + +pub fn convert_to_envoy_v2_to_v1(x: v2::ToEnvoy) -> Result { + Ok(match x { + v2::ToEnvoy::ToEnvoyInit(v) => v1::ToEnvoy::ToEnvoyInit(convert_to_envoy_init_v2_to_v1(v)?), + v2::ToEnvoy::ToEnvoyCommands(v) => { + v1::ToEnvoy::ToEnvoyCommands(convert_to_envoy_commands_v2_to_v1(v)?) + } + v2::ToEnvoy::ToEnvoyAckEvents(v) => { + v1::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v2_to_v1(v)?) + } + v2::ToEnvoy::ToEnvoyKvResponse(v) => { + v1::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v2_to_v1(v)?) + } + v2::ToEnvoy::ToEnvoyTunnelMessage(v) => { + v1::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v2_to_v1(v)?) + } + v2::ToEnvoy::ToEnvoyPing(v) => v1::ToEnvoy::ToEnvoyPing(convert_to_envoy_ping_v2_to_v1(v)?), + v2::ToEnvoy::ToEnvoySqliteGetPagesResponse(_) + | v2::ToEnvoy::ToEnvoySqliteCommitResponse(_) + | v2::ToEnvoy::ToEnvoySqliteCommitStageBeginResponse(_) + | v2::ToEnvoy::ToEnvoySqliteCommitStageResponse(_) + | v2::ToEnvoy::ToEnvoySqliteCommitFinalizeResponse(_) => { + bail!("sqlite responses require envoy-protocol v2") + } + }) +} + +pub fn convert_to_envoy_conn_ping_v2_to_v1(x: v2::ToEnvoyConnPing) -> Result { + Ok(v1::ToEnvoyConnPing { + gateway_id: x.gateway_id, + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_envoy_conn_v2_to_v1(x: v2::ToEnvoyConn) -> Result { + Ok(match x { + v2::ToEnvoyConn::ToEnvoyConnPing(v) => { + v1::ToEnvoyConn::ToEnvoyConnPing(convert_to_envoy_conn_ping_v2_to_v1(v)?) + } + v2::ToEnvoyConn::ToEnvoyConnClose => v1::ToEnvoyConn::ToEnvoyConnClose, + v2::ToEnvoyConn::ToEnvoyCommands(v) => { + v1::ToEnvoyConn::ToEnvoyCommands(convert_to_envoy_commands_v2_to_v1(v)?) + } + v2::ToEnvoyConn::ToEnvoyAckEvents(v) => { + v1::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v2_to_v1(v)?) + } + v2::ToEnvoyConn::ToEnvoyTunnelMessage(v) => { + v1::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v2_to_v1(v)?) + } + }) +} + +pub fn convert_to_gateway_pong_v2_to_v1(x: v2::ToGatewayPong) -> Result { + Ok(v1::ToGatewayPong { + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_gateway_v2_to_v1(x: v2::ToGateway) -> Result { + Ok(match x { + v2::ToGateway::ToGatewayPong(v) => { + v1::ToGateway::ToGatewayPong(convert_to_gateway_pong_v2_to_v1(v)?) + } + v2::ToGateway::ToRivetTunnelMessage(v) => { + v1::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v2_to_v1(v)?) + } + }) +} + +pub fn convert_to_outbound_actor_start_v2_to_v1( + x: v2::ToOutboundActorStart, +) -> Result { + Ok(v1::ToOutboundActorStart { + namespace_id: x.namespace_id, + pool_name: x.pool_name, + checkpoint: convert_actor_checkpoint_v2_to_v1(x.checkpoint)?, + actor_config: convert_actor_config_v2_to_v1(x.actor_config)?, + }) +} + +pub fn convert_to_outbound_v2_to_v1(x: v2::ToOutbound) -> Result { + Ok(match x { + v2::ToOutbound::ToOutboundActorStart(v) => { + v1::ToOutbound::ToOutboundActorStart(convert_to_outbound_actor_start_v2_to_v1(v)?) + } + }) +} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned/v2_to_v3.rs b/engine/sdks/rust/envoy-protocol/src/versioned/v2_to_v3.rs new file mode 100644 index 0000000000..5bdb428aeb --- /dev/null +++ b/engine/sdks/rust/envoy-protocol/src/versioned/v2_to_v3.rs @@ -0,0 +1,881 @@ +// @generated initial scaffold by scripts/vbare-gen-converters +// from: v2.bare, to: v3.bare +// Replace each todo!() with the migration semantics, then drop the @generated marker. + +#![allow(dead_code, unused_variables)] + +use anyhow::{Result, bail}; + +use crate::generated::{v2, v3}; + +pub fn convert_kv_metadata_v2_to_v3(x: v2::KvMetadata) -> Result { + Ok(v3::KvMetadata { + version: x.version, + update_ts: x.update_ts, + }) +} + +pub fn convert_kv_list_range_query_v2_to_v3( + x: v2::KvListRangeQuery, +) -> Result { + Ok(v3::KvListRangeQuery { + start: x.start, + end: x.end, + exclusive: x.exclusive, + }) +} + +pub fn convert_kv_list_prefix_query_v2_to_v3( + x: v2::KvListPrefixQuery, +) -> Result { + Ok(v3::KvListPrefixQuery { key: x.key }) +} + +pub fn convert_kv_list_query_v2_to_v3(x: v2::KvListQuery) -> Result { + Ok(match x { + v2::KvListQuery::KvListAllQuery => v3::KvListQuery::KvListAllQuery, + v2::KvListQuery::KvListRangeQuery(v) => { + v3::KvListQuery::KvListRangeQuery(convert_kv_list_range_query_v2_to_v3(v)?) + } + v2::KvListQuery::KvListPrefixQuery(v) => { + v3::KvListQuery::KvListPrefixQuery(convert_kv_list_prefix_query_v2_to_v3(v)?) + } + }) +} + +pub fn convert_kv_get_request_v2_to_v3(x: v2::KvGetRequest) -> Result { + Ok(v3::KvGetRequest { keys: x.keys }) +} + +pub fn convert_kv_list_request_v2_to_v3(x: v2::KvListRequest) -> Result { + Ok(v3::KvListRequest { + query: convert_kv_list_query_v2_to_v3(x.query)?, + reverse: x.reverse, + limit: x.limit, + }) +} + +pub fn convert_kv_put_request_v2_to_v3(x: v2::KvPutRequest) -> Result { + Ok(v3::KvPutRequest { + keys: x.keys, + values: x.values, + }) +} + +pub fn convert_kv_delete_request_v2_to_v3(x: v2::KvDeleteRequest) -> Result { + Ok(v3::KvDeleteRequest { keys: x.keys }) +} + +pub fn convert_kv_delete_range_request_v2_to_v3( + x: v2::KvDeleteRangeRequest, +) -> Result { + Ok(v3::KvDeleteRangeRequest { + start: x.start, + end: x.end, + }) +} + +pub fn convert_kv_error_response_v2_to_v3(x: v2::KvErrorResponse) -> Result { + Ok(v3::KvErrorResponse { message: x.message }) +} + +pub fn convert_kv_get_response_v2_to_v3(x: v2::KvGetResponse) -> Result { + Ok(v3::KvGetResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v2_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_list_response_v2_to_v3(x: v2::KvListResponse) -> Result { + Ok(v3::KvListResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v2_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_request_data_v2_to_v3(x: v2::KvRequestData) -> Result { + Ok(match x { + v2::KvRequestData::KvGetRequest(v) => { + v3::KvRequestData::KvGetRequest(convert_kv_get_request_v2_to_v3(v)?) + } + v2::KvRequestData::KvListRequest(v) => { + v3::KvRequestData::KvListRequest(convert_kv_list_request_v2_to_v3(v)?) + } + v2::KvRequestData::KvPutRequest(v) => { + v3::KvRequestData::KvPutRequest(convert_kv_put_request_v2_to_v3(v)?) + } + v2::KvRequestData::KvDeleteRequest(v) => { + v3::KvRequestData::KvDeleteRequest(convert_kv_delete_request_v2_to_v3(v)?) + } + v2::KvRequestData::KvDeleteRangeRequest(v) => { + v3::KvRequestData::KvDeleteRangeRequest(convert_kv_delete_range_request_v2_to_v3(v)?) + } + v2::KvRequestData::KvDropRequest => v3::KvRequestData::KvDropRequest, + }) +} + +pub fn convert_kv_response_data_v2_to_v3(x: v2::KvResponseData) -> Result { + Ok(match x { + v2::KvResponseData::KvErrorResponse(v) => { + v3::KvResponseData::KvErrorResponse(convert_kv_error_response_v2_to_v3(v)?) + } + v2::KvResponseData::KvGetResponse(v) => { + v3::KvResponseData::KvGetResponse(convert_kv_get_response_v2_to_v3(v)?) + } + v2::KvResponseData::KvListResponse(v) => { + v3::KvResponseData::KvListResponse(convert_kv_list_response_v2_to_v3(v)?) + } + v2::KvResponseData::KvPutResponse => v3::KvResponseData::KvPutResponse, + v2::KvResponseData::KvDeleteResponse => v3::KvResponseData::KvDeleteResponse, + v2::KvResponseData::KvDropResponse => v3::KvResponseData::KvDropResponse, + }) +} + +pub fn convert_sqlite_dirty_page_v2_to_v3(x: v2::SqliteDirtyPage) -> Result { + Ok(v3::SqliteDirtyPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_fetched_page_v2_to_v3( + x: v2::SqliteFetchedPage, +) -> Result { + Ok(v3::SqliteFetchedPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_get_pages_request_v2_to_v3( + x: v2::SqliteGetPagesRequest, +) -> Result { + Ok(v3::SqliteGetPagesRequest { + actor_id: x.actor_id, + pgnos: x.pgnos, + expected_generation: todo!(), + expected_head_txid: todo!(), + }) +} + +pub fn convert_sqlite_get_pages_ok_v2_to_v3( + x: v2::SqliteGetPagesOk, +) -> Result { + Ok(v3::SqliteGetPagesOk { + pages: x + .pages + .into_iter() + .map(|v| convert_sqlite_fetched_page_v2_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_sqlite_error_response_v2_to_v3( + x: v2::SqliteErrorResponse, +) -> Result { + Ok(v3::SqliteErrorResponse { message: x.message }) +} + +pub fn convert_sqlite_get_pages_response_v2_to_v3( + x: v2::SqliteGetPagesResponse, +) -> Result { + Ok(match x { + v2::SqliteGetPagesResponse::SqliteGetPagesOk(v) => { + v3::SqliteGetPagesResponse::SqliteGetPagesOk(convert_sqlite_get_pages_ok_v2_to_v3(v)?) + } + v2::SqliteGetPagesResponse::SqliteFenceMismatch(_) => todo!(), + v2::SqliteGetPagesResponse::SqliteErrorResponse(v) => { + v3::SqliteGetPagesResponse::SqliteErrorResponse(convert_sqlite_error_response_v2_to_v3( + v, + )?) + } + }) +} + +pub fn convert_sqlite_commit_request_v2_to_v3( + x: v2::SqliteCommitRequest, +) -> Result { + Ok(v3::SqliteCommitRequest { + actor_id: x.actor_id, + dirty_pages: x + .dirty_pages + .into_iter() + .map(|v| convert_sqlite_dirty_page_v2_to_v3(v)) + .collect::>>()?, + db_size_pages: todo!(), + now_ms: todo!(), + expected_generation: todo!(), + expected_head_txid: todo!(), + }) +} + +pub fn convert_sqlite_commit_response_v2_to_v3( + x: v2::SqliteCommitResponse, +) -> Result { + Ok(match x { + v2::SqliteCommitResponse::SqliteCommitOk(_) => todo!(), + v2::SqliteCommitResponse::SqliteFenceMismatch(_) => todo!(), + v2::SqliteCommitResponse::SqliteCommitTooLarge(_) => todo!(), + v2::SqliteCommitResponse::SqliteErrorResponse(v) => { + v3::SqliteCommitResponse::SqliteErrorResponse(convert_sqlite_error_response_v2_to_v3( + v, + )?) + } + }) +} + +pub fn convert_stop_code_v2_to_v3(x: v2::StopCode) -> Result { + Ok(match x { + v2::StopCode::Ok => v3::StopCode::Ok, + v2::StopCode::Error => v3::StopCode::Error, + }) +} + +pub fn convert_actor_name_v2_to_v3(x: v2::ActorName) -> Result { + Ok(v3::ActorName { + metadata: x.metadata, + }) +} + +pub fn convert_actor_config_v2_to_v3(x: v2::ActorConfig) -> Result { + Ok(v3::ActorConfig { + name: x.name, + key: x.key, + create_ts: x.create_ts, + input: x.input, + }) +} + +pub fn convert_actor_checkpoint_v2_to_v3(x: v2::ActorCheckpoint) -> Result { + Ok(v3::ActorCheckpoint { + actor_id: x.actor_id, + generation: x.generation, + index: x.index, + }) +} + +pub fn convert_actor_intent_v2_to_v3(x: v2::ActorIntent) -> Result { + Ok(match x { + v2::ActorIntent::ActorIntentSleep => v3::ActorIntent::ActorIntentSleep, + v2::ActorIntent::ActorIntentStop => v3::ActorIntent::ActorIntentStop, + }) +} + +pub fn convert_actor_state_stopped_v2_to_v3( + x: v2::ActorStateStopped, +) -> Result { + Ok(v3::ActorStateStopped { + code: convert_stop_code_v2_to_v3(x.code)?, + message: x.message, + }) +} + +pub fn convert_actor_state_v2_to_v3(x: v2::ActorState) -> Result { + Ok(match x { + v2::ActorState::ActorStateRunning => v3::ActorState::ActorStateRunning, + v2::ActorState::ActorStateStopped(v) => { + v3::ActorState::ActorStateStopped(convert_actor_state_stopped_v2_to_v3(v)?) + } + }) +} + +pub fn convert_event_actor_intent_v2_to_v3( + x: v2::EventActorIntent, +) -> Result { + Ok(v3::EventActorIntent { + intent: convert_actor_intent_v2_to_v3(x.intent)?, + }) +} + +pub fn convert_event_actor_state_update_v2_to_v3( + x: v2::EventActorStateUpdate, +) -> Result { + Ok(v3::EventActorStateUpdate { + state: convert_actor_state_v2_to_v3(x.state)?, + }) +} + +pub fn convert_event_actor_set_alarm_v2_to_v3( + x: v2::EventActorSetAlarm, +) -> Result { + Ok(v3::EventActorSetAlarm { + alarm_ts: x.alarm_ts, + }) +} + +pub fn convert_event_v2_to_v3(x: v2::Event) -> Result { + Ok(match x { + v2::Event::EventActorIntent(v) => { + v3::Event::EventActorIntent(convert_event_actor_intent_v2_to_v3(v)?) + } + v2::Event::EventActorStateUpdate(v) => { + v3::Event::EventActorStateUpdate(convert_event_actor_state_update_v2_to_v3(v)?) + } + v2::Event::EventActorSetAlarm(v) => { + v3::Event::EventActorSetAlarm(convert_event_actor_set_alarm_v2_to_v3(v)?) + } + }) +} + +pub fn convert_event_wrapper_v2_to_v3(x: v2::EventWrapper) -> Result { + Ok(v3::EventWrapper { + checkpoint: convert_actor_checkpoint_v2_to_v3(x.checkpoint)?, + inner: convert_event_v2_to_v3(x.inner)?, + }) +} + +pub fn convert_preloaded_kv_entry_v2_to_v3( + x: v2::PreloadedKvEntry, +) -> Result { + Ok(v3::PreloadedKvEntry { + key: x.key, + value: x.value, + metadata: convert_kv_metadata_v2_to_v3(x.metadata)?, + }) +} + +pub fn convert_preloaded_kv_v2_to_v3(x: v2::PreloadedKv) -> Result { + Ok(v3::PreloadedKv { + entries: x + .entries + .into_iter() + .map(|v| convert_preloaded_kv_entry_v2_to_v3(v)) + .collect::>>()?, + requested_get_keys: x.requested_get_keys, + requested_prefixes: x.requested_prefixes, + }) +} + +pub fn convert_hibernating_request_v2_to_v3( + x: v2::HibernatingRequest, +) -> Result { + Ok(v3::HibernatingRequest { + gateway_id: x.gateway_id, + request_id: x.request_id, + }) +} + +pub fn convert_command_start_actor_v2_to_v3( + x: v2::CommandStartActor, +) -> Result { + Ok(v3::CommandStartActor { + config: convert_actor_config_v2_to_v3(x.config)?, + hibernating_requests: x + .hibernating_requests + .into_iter() + .map(|v| convert_hibernating_request_v2_to_v3(v)) + .collect::>>()?, + preloaded_kv: x + .preloaded_kv + .map(|v| convert_preloaded_kv_v2_to_v3(v)) + .transpose()?, + }) +} + +pub fn convert_stop_actor_reason_v2_to_v3(x: v2::StopActorReason) -> Result { + Ok(match x { + v2::StopActorReason::SleepIntent => v3::StopActorReason::SleepIntent, + v2::StopActorReason::StopIntent => v3::StopActorReason::StopIntent, + v2::StopActorReason::Destroy => v3::StopActorReason::Destroy, + v2::StopActorReason::GoingAway => v3::StopActorReason::GoingAway, + v2::StopActorReason::Lost => v3::StopActorReason::Lost, + }) +} + +pub fn convert_command_stop_actor_v2_to_v3( + x: v2::CommandStopActor, +) -> Result { + Ok(v3::CommandStopActor { + reason: convert_stop_actor_reason_v2_to_v3(x.reason)?, + }) +} + +pub fn convert_command_v2_to_v3(x: v2::Command) -> Result { + Ok(match x { + v2::Command::CommandStartActor(v) => { + v3::Command::CommandStartActor(convert_command_start_actor_v2_to_v3(v)?) + } + v2::Command::CommandStopActor(v) => { + v3::Command::CommandStopActor(convert_command_stop_actor_v2_to_v3(v)?) + } + }) +} + +pub fn convert_command_wrapper_v2_to_v3(x: v2::CommandWrapper) -> Result { + Ok(v3::CommandWrapper { + checkpoint: convert_actor_checkpoint_v2_to_v3(x.checkpoint)?, + inner: convert_command_v2_to_v3(x.inner)?, + }) +} + +pub fn convert_actor_command_key_data_v2_to_v3( + x: v2::ActorCommandKeyData, +) -> Result { + Ok(match x { + v2::ActorCommandKeyData::CommandStartActor(v) => { + v3::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v2_to_v3(v)?) + } + v2::ActorCommandKeyData::CommandStopActor(v) => { + v3::ActorCommandKeyData::CommandStopActor(convert_command_stop_actor_v2_to_v3(v)?) + } + }) +} + +pub fn convert_message_id_v2_to_v3(x: v2::MessageId) -> Result { + Ok(v3::MessageId { + gateway_id: x.gateway_id, + request_id: x.request_id, + message_index: x.message_index, + }) +} + +pub fn convert_to_envoy_request_start_v2_to_v3( + x: v2::ToEnvoyRequestStart, +) -> Result { + Ok(v3::ToEnvoyRequestStart { + actor_id: x.actor_id, + method: x.method, + path: x.path, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_envoy_request_chunk_v2_to_v3( + x: v2::ToEnvoyRequestChunk, +) -> Result { + Ok(v3::ToEnvoyRequestChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_rivet_response_start_v2_to_v3( + x: v2::ToRivetResponseStart, +) -> Result { + Ok(v3::ToRivetResponseStart { + status: x.status, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_rivet_response_chunk_v2_to_v3( + x: v2::ToRivetResponseChunk, +) -> Result { + Ok(v3::ToRivetResponseChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_envoy_web_socket_open_v2_to_v3( + x: v2::ToEnvoyWebSocketOpen, +) -> Result { + Ok(v3::ToEnvoyWebSocketOpen { + actor_id: x.actor_id, + path: x.path, + headers: x.headers, + }) +} + +pub fn convert_to_envoy_web_socket_message_v2_to_v3( + x: v2::ToEnvoyWebSocketMessage, +) -> Result { + Ok(v3::ToEnvoyWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_envoy_web_socket_close_v2_to_v3( + x: v2::ToEnvoyWebSocketClose, +) -> Result { + Ok(v3::ToEnvoyWebSocketClose { + code: x.code, + reason: x.reason, + }) +} + +pub fn convert_to_rivet_web_socket_open_v2_to_v3( + x: v2::ToRivetWebSocketOpen, +) -> Result { + Ok(v3::ToRivetWebSocketOpen { + can_hibernate: x.can_hibernate, + }) +} + +pub fn convert_to_rivet_web_socket_message_v2_to_v3( + x: v2::ToRivetWebSocketMessage, +) -> Result { + Ok(v3::ToRivetWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_rivet_web_socket_message_ack_v2_to_v3( + x: v2::ToRivetWebSocketMessageAck, +) -> Result { + Ok(v3::ToRivetWebSocketMessageAck { index: x.index }) +} + +pub fn convert_to_rivet_web_socket_close_v2_to_v3( + x: v2::ToRivetWebSocketClose, +) -> Result { + Ok(v3::ToRivetWebSocketClose { + code: x.code, + reason: x.reason, + hibernate: x.hibernate, + }) +} + +pub fn convert_to_rivet_tunnel_message_kind_v2_to_v3( + x: v2::ToRivetTunnelMessageKind, +) -> Result { + Ok(match x { + v2::ToRivetTunnelMessageKind::ToRivetResponseStart(v) => { + v3::ToRivetTunnelMessageKind::ToRivetResponseStart( + convert_to_rivet_response_start_v2_to_v3(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetResponseChunk(v) => { + v3::ToRivetTunnelMessageKind::ToRivetResponseChunk( + convert_to_rivet_response_chunk_v2_to_v3(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetResponseAbort => { + v3::ToRivetTunnelMessageKind::ToRivetResponseAbort + } + v2::ToRivetTunnelMessageKind::ToRivetWebSocketOpen(v) => { + v3::ToRivetTunnelMessageKind::ToRivetWebSocketOpen( + convert_to_rivet_web_socket_open_v2_to_v3(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetWebSocketMessage(v) => { + v3::ToRivetTunnelMessageKind::ToRivetWebSocketMessage( + convert_to_rivet_web_socket_message_v2_to_v3(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck(v) => { + v3::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck( + convert_to_rivet_web_socket_message_ack_v2_to_v3(v)?, + ) + } + v2::ToRivetTunnelMessageKind::ToRivetWebSocketClose(v) => { + v3::ToRivetTunnelMessageKind::ToRivetWebSocketClose( + convert_to_rivet_web_socket_close_v2_to_v3(v)?, + ) + } + }) +} + +pub fn convert_to_rivet_tunnel_message_v2_to_v3( + x: v2::ToRivetTunnelMessage, +) -> Result { + Ok(v3::ToRivetTunnelMessage { + message_id: convert_message_id_v2_to_v3(x.message_id)?, + message_kind: convert_to_rivet_tunnel_message_kind_v2_to_v3(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_tunnel_message_kind_v2_to_v3( + x: v2::ToEnvoyTunnelMessageKind, +) -> Result { + Ok(match x { + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart( + convert_to_envoy_request_start_v2_to_v3(v)?, + ) + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk( + convert_to_envoy_request_chunk_v2_to_v3(v)?, + ) + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen( + convert_to_envoy_web_socket_open_v2_to_v3(v)?, + ) + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage( + convert_to_envoy_web_socket_message_v2_to_v3(v)?, + ) + } + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose( + convert_to_envoy_web_socket_close_v2_to_v3(v)?, + ) + } + }) +} + +pub fn convert_to_envoy_tunnel_message_v2_to_v3( + x: v2::ToEnvoyTunnelMessage, +) -> Result { + Ok(v3::ToEnvoyTunnelMessage { + message_id: convert_message_id_v2_to_v3(x.message_id)?, + message_kind: convert_to_envoy_tunnel_message_kind_v2_to_v3(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_ping_v2_to_v3(x: v2::ToEnvoyPing) -> Result { + Ok(v3::ToEnvoyPing { ts: x.ts }) +} + +pub fn convert_to_rivet_metadata_v2_to_v3(x: v2::ToRivetMetadata) -> Result { + Ok(v3::ToRivetMetadata { + prepopulate_actor_names: x + .prepopulate_actor_names + .map(|v| { + v.into_iter() + .map(|(k, v)| -> Result<_> { Ok((k, convert_actor_name_v2_to_v3(v)?)) }) + .collect::>() + }) + .transpose()?, + metadata: x.metadata, + }) +} + +pub fn convert_to_rivet_events_v2_to_v3(x: v2::ToRivetEvents) -> Result { + Ok(x.into_iter() + .map(|v| convert_event_wrapper_v2_to_v3(v)) + .collect::>>()?) +} + +pub fn convert_to_rivet_ack_commands_v2_to_v3( + x: v2::ToRivetAckCommands, +) -> Result { + Ok(v3::ToRivetAckCommands { + last_command_checkpoints: x + .last_command_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v2_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_rivet_pong_v2_to_v3(x: v2::ToRivetPong) -> Result { + Ok(v3::ToRivetPong { ts: x.ts }) +} + +pub fn convert_to_rivet_kv_request_v2_to_v3( + x: v2::ToRivetKvRequest, +) -> Result { + Ok(v3::ToRivetKvRequest { + actor_id: x.actor_id, + request_id: x.request_id, + data: convert_kv_request_data_v2_to_v3(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_get_pages_request_v2_to_v3( + x: v2::ToRivetSqliteGetPagesRequest, +) -> Result { + Ok(v3::ToRivetSqliteGetPagesRequest { + request_id: x.request_id, + data: convert_sqlite_get_pages_request_v2_to_v3(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_commit_request_v2_to_v3( + x: v2::ToRivetSqliteCommitRequest, +) -> Result { + Ok(v3::ToRivetSqliteCommitRequest { + request_id: x.request_id, + data: convert_sqlite_commit_request_v2_to_v3(x.data)?, + }) +} + +pub fn convert_to_rivet_v2_to_v3(x: v2::ToRivet) -> Result { + Ok(match x { + v2::ToRivet::ToRivetMetadata(v) => { + v3::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v2_to_v3(v)?) + } + v2::ToRivet::ToRivetEvents(v) => { + v3::ToRivet::ToRivetEvents(convert_to_rivet_events_v2_to_v3(v)?) + } + v2::ToRivet::ToRivetAckCommands(v) => { + v3::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v2_to_v3(v)?) + } + v2::ToRivet::ToRivetStopping => v3::ToRivet::ToRivetStopping, + v2::ToRivet::ToRivetPong(v) => v3::ToRivet::ToRivetPong(convert_to_rivet_pong_v2_to_v3(v)?), + v2::ToRivet::ToRivetKvRequest(v) => { + v3::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v2_to_v3(v)?) + } + v2::ToRivet::ToRivetTunnelMessage(v) => { + v3::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v2_to_v3(v)?) + } + v2::ToRivet::ToRivetSqliteGetPagesRequest(_) + | v2::ToRivet::ToRivetSqliteCommitRequest(_) + | v2::ToRivet::ToRivetSqliteCommitStageBeginRequest(_) + | v2::ToRivet::ToRivetSqliteCommitStageRequest(_) + | v2::ToRivet::ToRivetSqliteCommitFinalizeRequest(_) => { + bail!("legacy sqlite requests require envoy-protocol v2") + } + }) +} + +pub fn convert_protocol_metadata_v2_to_v3(x: v2::ProtocolMetadata) -> Result { + Ok(v3::ProtocolMetadata { + envoy_lost_threshold: x.envoy_lost_threshold, + actor_stop_threshold: x.actor_stop_threshold, + max_response_payload_size: x.max_response_payload_size, + }) +} + +pub fn convert_to_envoy_init_v2_to_v3(x: v2::ToEnvoyInit) -> Result { + Ok(v3::ToEnvoyInit { + metadata: convert_protocol_metadata_v2_to_v3(x.metadata)?, + }) +} + +pub fn convert_to_envoy_commands_v2_to_v3(x: v2::ToEnvoyCommands) -> Result { + Ok(x.into_iter() + .map(|v| convert_command_wrapper_v2_to_v3(v)) + .collect::>>()?) +} + +pub fn convert_to_envoy_ack_events_v2_to_v3( + x: v2::ToEnvoyAckEvents, +) -> Result { + Ok(v3::ToEnvoyAckEvents { + last_event_checkpoints: x + .last_event_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v2_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_envoy_kv_response_v2_to_v3( + x: v2::ToEnvoyKvResponse, +) -> Result { + Ok(v3::ToEnvoyKvResponse { + request_id: x.request_id, + data: convert_kv_response_data_v2_to_v3(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_get_pages_response_v2_to_v3( + x: v2::ToEnvoySqliteGetPagesResponse, +) -> Result { + Ok(v3::ToEnvoySqliteGetPagesResponse { + request_id: x.request_id, + data: convert_sqlite_get_pages_response_v2_to_v3(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_commit_response_v2_to_v3( + x: v2::ToEnvoySqliteCommitResponse, +) -> Result { + Ok(v3::ToEnvoySqliteCommitResponse { + request_id: x.request_id, + data: convert_sqlite_commit_response_v2_to_v3(x.data)?, + }) +} + +pub fn convert_to_envoy_v2_to_v3(x: v2::ToEnvoy) -> Result { + Ok(match x { + v2::ToEnvoy::ToEnvoyInit(v) => v3::ToEnvoy::ToEnvoyInit(convert_to_envoy_init_v2_to_v3(v)?), + v2::ToEnvoy::ToEnvoyCommands(v) => { + v3::ToEnvoy::ToEnvoyCommands(convert_to_envoy_commands_v2_to_v3(v)?) + } + v2::ToEnvoy::ToEnvoyAckEvents(v) => { + v3::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v2_to_v3(v)?) + } + v2::ToEnvoy::ToEnvoyKvResponse(v) => { + v3::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v2_to_v3(v)?) + } + v2::ToEnvoy::ToEnvoyTunnelMessage(v) => { + v3::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v2_to_v3(v)?) + } + v2::ToEnvoy::ToEnvoyPing(v) => v3::ToEnvoy::ToEnvoyPing(convert_to_envoy_ping_v2_to_v3(v)?), + v2::ToEnvoy::ToEnvoySqliteGetPagesResponse(_) + | v2::ToEnvoy::ToEnvoySqliteCommitResponse(_) + | v2::ToEnvoy::ToEnvoySqliteCommitStageBeginResponse(_) + | v2::ToEnvoy::ToEnvoySqliteCommitStageResponse(_) + | v2::ToEnvoy::ToEnvoySqliteCommitFinalizeResponse(_) => { + bail!("legacy sqlite responses require envoy-protocol v2") + } + }) +} + +pub fn convert_to_envoy_conn_ping_v2_to_v3(x: v2::ToEnvoyConnPing) -> Result { + Ok(v3::ToEnvoyConnPing { + gateway_id: x.gateway_id, + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_envoy_conn_v2_to_v3(x: v2::ToEnvoyConn) -> Result { + Ok(match x { + v2::ToEnvoyConn::ToEnvoyConnPing(v) => { + v3::ToEnvoyConn::ToEnvoyConnPing(convert_to_envoy_conn_ping_v2_to_v3(v)?) + } + v2::ToEnvoyConn::ToEnvoyConnClose => v3::ToEnvoyConn::ToEnvoyConnClose, + v2::ToEnvoyConn::ToEnvoyCommands(v) => { + v3::ToEnvoyConn::ToEnvoyCommands(convert_to_envoy_commands_v2_to_v3(v)?) + } + v2::ToEnvoyConn::ToEnvoyAckEvents(v) => { + v3::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v2_to_v3(v)?) + } + v2::ToEnvoyConn::ToEnvoyTunnelMessage(v) => { + v3::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v2_to_v3(v)?) + } + }) +} + +pub fn convert_to_gateway_pong_v2_to_v3(x: v2::ToGatewayPong) -> Result { + Ok(v3::ToGatewayPong { + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_gateway_v2_to_v3(x: v2::ToGateway) -> Result { + Ok(match x { + v2::ToGateway::ToGatewayPong(v) => { + v3::ToGateway::ToGatewayPong(convert_to_gateway_pong_v2_to_v3(v)?) + } + v2::ToGateway::ToRivetTunnelMessage(v) => { + v3::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v2_to_v3(v)?) + } + }) +} + +pub fn convert_to_outbound_actor_start_v2_to_v3( + x: v2::ToOutboundActorStart, +) -> Result { + Ok(v3::ToOutboundActorStart { + namespace_id: x.namespace_id, + pool_name: x.pool_name, + checkpoint: convert_actor_checkpoint_v2_to_v3(x.checkpoint)?, + actor_config: convert_actor_config_v2_to_v3(x.actor_config)?, + }) +} + +pub fn convert_to_outbound_v2_to_v3(x: v2::ToOutbound) -> Result { + Ok(match x { + v2::ToOutbound::ToOutboundActorStart(v) => { + v3::ToOutbound::ToOutboundActorStart(convert_to_outbound_actor_start_v2_to_v3(v)?) + } + }) +} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned/v3_to_v2.rs b/engine/sdks/rust/envoy-protocol/src/versioned/v3_to_v2.rs new file mode 100644 index 0000000000..9f95bbdb83 --- /dev/null +++ b/engine/sdks/rust/envoy-protocol/src/versioned/v3_to_v2.rs @@ -0,0 +1,873 @@ +// @generated initial scaffold by scripts/vbare-gen-converters +// from: v3.bare, to: v2.bare +// Replace each todo!() with the migration semantics, then drop the @generated marker. + +#![allow(dead_code, unused_variables)] + +use anyhow::{Result, bail}; + +use crate::generated::{v2, v3}; + +pub fn convert_kv_metadata_v3_to_v2(x: v3::KvMetadata) -> Result { + Ok(v2::KvMetadata { + version: x.version, + update_ts: x.update_ts, + }) +} + +pub fn convert_kv_list_range_query_v3_to_v2( + x: v3::KvListRangeQuery, +) -> Result { + Ok(v2::KvListRangeQuery { + start: x.start, + end: x.end, + exclusive: x.exclusive, + }) +} + +pub fn convert_kv_list_prefix_query_v3_to_v2( + x: v3::KvListPrefixQuery, +) -> Result { + Ok(v2::KvListPrefixQuery { key: x.key }) +} + +pub fn convert_kv_list_query_v3_to_v2(x: v3::KvListQuery) -> Result { + Ok(match x { + v3::KvListQuery::KvListAllQuery => v2::KvListQuery::KvListAllQuery, + v3::KvListQuery::KvListRangeQuery(v) => { + v2::KvListQuery::KvListRangeQuery(convert_kv_list_range_query_v3_to_v2(v)?) + } + v3::KvListQuery::KvListPrefixQuery(v) => { + v2::KvListQuery::KvListPrefixQuery(convert_kv_list_prefix_query_v3_to_v2(v)?) + } + }) +} + +pub fn convert_kv_get_request_v3_to_v2(x: v3::KvGetRequest) -> Result { + Ok(v2::KvGetRequest { keys: x.keys }) +} + +pub fn convert_kv_list_request_v3_to_v2(x: v3::KvListRequest) -> Result { + Ok(v2::KvListRequest { + query: convert_kv_list_query_v3_to_v2(x.query)?, + reverse: x.reverse, + limit: x.limit, + }) +} + +pub fn convert_kv_put_request_v3_to_v2(x: v3::KvPutRequest) -> Result { + Ok(v2::KvPutRequest { + keys: x.keys, + values: x.values, + }) +} + +pub fn convert_kv_delete_request_v3_to_v2(x: v3::KvDeleteRequest) -> Result { + Ok(v2::KvDeleteRequest { keys: x.keys }) +} + +pub fn convert_kv_delete_range_request_v3_to_v2( + x: v3::KvDeleteRangeRequest, +) -> Result { + Ok(v2::KvDeleteRangeRequest { + start: x.start, + end: x.end, + }) +} + +pub fn convert_kv_error_response_v3_to_v2(x: v3::KvErrorResponse) -> Result { + Ok(v2::KvErrorResponse { message: x.message }) +} + +pub fn convert_kv_get_response_v3_to_v2(x: v3::KvGetResponse) -> Result { + Ok(v2::KvGetResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v3_to_v2(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_list_response_v3_to_v2(x: v3::KvListResponse) -> Result { + Ok(v2::KvListResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v3_to_v2(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_request_data_v3_to_v2(x: v3::KvRequestData) -> Result { + Ok(match x { + v3::KvRequestData::KvGetRequest(v) => { + v2::KvRequestData::KvGetRequest(convert_kv_get_request_v3_to_v2(v)?) + } + v3::KvRequestData::KvListRequest(v) => { + v2::KvRequestData::KvListRequest(convert_kv_list_request_v3_to_v2(v)?) + } + v3::KvRequestData::KvPutRequest(v) => { + v2::KvRequestData::KvPutRequest(convert_kv_put_request_v3_to_v2(v)?) + } + v3::KvRequestData::KvDeleteRequest(v) => { + v2::KvRequestData::KvDeleteRequest(convert_kv_delete_request_v3_to_v2(v)?) + } + v3::KvRequestData::KvDeleteRangeRequest(v) => { + v2::KvRequestData::KvDeleteRangeRequest(convert_kv_delete_range_request_v3_to_v2(v)?) + } + v3::KvRequestData::KvDropRequest => v2::KvRequestData::KvDropRequest, + }) +} + +pub fn convert_kv_response_data_v3_to_v2(x: v3::KvResponseData) -> Result { + Ok(match x { + v3::KvResponseData::KvErrorResponse(v) => { + v2::KvResponseData::KvErrorResponse(convert_kv_error_response_v3_to_v2(v)?) + } + v3::KvResponseData::KvGetResponse(v) => { + v2::KvResponseData::KvGetResponse(convert_kv_get_response_v3_to_v2(v)?) + } + v3::KvResponseData::KvListResponse(v) => { + v2::KvResponseData::KvListResponse(convert_kv_list_response_v3_to_v2(v)?) + } + v3::KvResponseData::KvPutResponse => v2::KvResponseData::KvPutResponse, + v3::KvResponseData::KvDeleteResponse => v2::KvResponseData::KvDeleteResponse, + v3::KvResponseData::KvDropResponse => v2::KvResponseData::KvDropResponse, + }) +} + +pub fn convert_sqlite_dirty_page_v3_to_v2(x: v3::SqliteDirtyPage) -> Result { + Ok(v2::SqliteDirtyPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_fetched_page_v3_to_v2( + x: v3::SqliteFetchedPage, +) -> Result { + Ok(v2::SqliteFetchedPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_get_pages_request_v3_to_v2( + x: v3::SqliteGetPagesRequest, +) -> Result { + Ok(v2::SqliteGetPagesRequest { + actor_id: x.actor_id, + generation: todo!(), + pgnos: x.pgnos, + }) +} + +pub fn convert_sqlite_get_pages_ok_v3_to_v2( + x: v3::SqliteGetPagesOk, +) -> Result { + Ok(v2::SqliteGetPagesOk { + pages: x + .pages + .into_iter() + .map(|v| convert_sqlite_fetched_page_v3_to_v2(v)) + .collect::>>()?, + meta: todo!(), + }) +} + +pub fn convert_sqlite_error_response_v3_to_v2( + x: v3::SqliteErrorResponse, +) -> Result { + Ok(v2::SqliteErrorResponse { message: x.message }) +} + +pub fn convert_sqlite_get_pages_response_v3_to_v2( + x: v3::SqliteGetPagesResponse, +) -> Result { + Ok(match x { + v3::SqliteGetPagesResponse::SqliteGetPagesOk(v) => { + v2::SqliteGetPagesResponse::SqliteGetPagesOk(convert_sqlite_get_pages_ok_v3_to_v2(v)?) + } + v3::SqliteGetPagesResponse::SqliteErrorResponse(v) => { + v2::SqliteGetPagesResponse::SqliteErrorResponse(convert_sqlite_error_response_v3_to_v2( + v, + )?) + } + }) +} + +pub fn convert_sqlite_commit_request_v3_to_v2( + x: v3::SqliteCommitRequest, +) -> Result { + Ok(v2::SqliteCommitRequest { + actor_id: x.actor_id, + generation: todo!(), + expected_head_txid: todo!(), + dirty_pages: x + .dirty_pages + .into_iter() + .map(|v| convert_sqlite_dirty_page_v3_to_v2(v)) + .collect::>>()?, + new_db_size_pages: todo!(), + }) +} + +pub fn convert_sqlite_commit_response_v3_to_v2( + x: v3::SqliteCommitResponse, +) -> Result { + Ok(match x { + v3::SqliteCommitResponse::SqliteCommitOk => todo!(), + v3::SqliteCommitResponse::SqliteErrorResponse(v) => { + v2::SqliteCommitResponse::SqliteErrorResponse(convert_sqlite_error_response_v3_to_v2( + v, + )?) + } + }) +} + +pub fn convert_stop_code_v3_to_v2(x: v3::StopCode) -> Result { + Ok(match x { + v3::StopCode::Ok => v2::StopCode::Ok, + v3::StopCode::Error => v2::StopCode::Error, + }) +} + +pub fn convert_actor_name_v3_to_v2(x: v3::ActorName) -> Result { + Ok(v2::ActorName { + metadata: x.metadata, + }) +} + +pub fn convert_actor_config_v3_to_v2(x: v3::ActorConfig) -> Result { + Ok(v2::ActorConfig { + name: x.name, + key: x.key, + create_ts: x.create_ts, + input: x.input, + }) +} + +pub fn convert_actor_checkpoint_v3_to_v2(x: v3::ActorCheckpoint) -> Result { + Ok(v2::ActorCheckpoint { + actor_id: x.actor_id, + generation: x.generation, + index: x.index, + }) +} + +pub fn convert_actor_intent_v3_to_v2(x: v3::ActorIntent) -> Result { + Ok(match x { + v3::ActorIntent::ActorIntentSleep => v2::ActorIntent::ActorIntentSleep, + v3::ActorIntent::ActorIntentStop => v2::ActorIntent::ActorIntentStop, + }) +} + +pub fn convert_actor_state_stopped_v3_to_v2( + x: v3::ActorStateStopped, +) -> Result { + Ok(v2::ActorStateStopped { + code: convert_stop_code_v3_to_v2(x.code)?, + message: x.message, + }) +} + +pub fn convert_actor_state_v3_to_v2(x: v3::ActorState) -> Result { + Ok(match x { + v3::ActorState::ActorStateRunning => v2::ActorState::ActorStateRunning, + v3::ActorState::ActorStateStopped(v) => { + v2::ActorState::ActorStateStopped(convert_actor_state_stopped_v3_to_v2(v)?) + } + }) +} + +pub fn convert_event_actor_intent_v3_to_v2( + x: v3::EventActorIntent, +) -> Result { + Ok(v2::EventActorIntent { + intent: convert_actor_intent_v3_to_v2(x.intent)?, + }) +} + +pub fn convert_event_actor_state_update_v3_to_v2( + x: v3::EventActorStateUpdate, +) -> Result { + Ok(v2::EventActorStateUpdate { + state: convert_actor_state_v3_to_v2(x.state)?, + }) +} + +pub fn convert_event_actor_set_alarm_v3_to_v2( + x: v3::EventActorSetAlarm, +) -> Result { + Ok(v2::EventActorSetAlarm { + alarm_ts: x.alarm_ts, + }) +} + +pub fn convert_event_v3_to_v2(x: v3::Event) -> Result { + Ok(match x { + v3::Event::EventActorIntent(v) => { + v2::Event::EventActorIntent(convert_event_actor_intent_v3_to_v2(v)?) + } + v3::Event::EventActorStateUpdate(v) => { + v2::Event::EventActorStateUpdate(convert_event_actor_state_update_v3_to_v2(v)?) + } + v3::Event::EventActorSetAlarm(v) => { + v2::Event::EventActorSetAlarm(convert_event_actor_set_alarm_v3_to_v2(v)?) + } + }) +} + +pub fn convert_event_wrapper_v3_to_v2(x: v3::EventWrapper) -> Result { + Ok(v2::EventWrapper { + checkpoint: convert_actor_checkpoint_v3_to_v2(x.checkpoint)?, + inner: convert_event_v3_to_v2(x.inner)?, + }) +} + +pub fn convert_preloaded_kv_entry_v3_to_v2( + x: v3::PreloadedKvEntry, +) -> Result { + Ok(v2::PreloadedKvEntry { + key: x.key, + value: x.value, + metadata: convert_kv_metadata_v3_to_v2(x.metadata)?, + }) +} + +pub fn convert_preloaded_kv_v3_to_v2(x: v3::PreloadedKv) -> Result { + Ok(v2::PreloadedKv { + entries: x + .entries + .into_iter() + .map(|v| convert_preloaded_kv_entry_v3_to_v2(v)) + .collect::>>()?, + requested_get_keys: x.requested_get_keys, + requested_prefixes: x.requested_prefixes, + }) +} + +pub fn convert_hibernating_request_v3_to_v2( + x: v3::HibernatingRequest, +) -> Result { + Ok(v2::HibernatingRequest { + gateway_id: x.gateway_id, + request_id: x.request_id, + }) +} + +pub fn convert_command_start_actor_v3_to_v2( + x: v3::CommandStartActor, +) -> Result { + Ok(v2::CommandStartActor { + config: convert_actor_config_v3_to_v2(x.config)?, + hibernating_requests: x + .hibernating_requests + .into_iter() + .map(|v| convert_hibernating_request_v3_to_v2(v)) + .collect::>>()?, + preloaded_kv: x + .preloaded_kv + .map(|v| convert_preloaded_kv_v3_to_v2(v)) + .transpose()?, + // v3 dropped the field; downgrade leaves it absent on the v2 wire. + sqlite_startup_data: None, + }) +} + +pub fn convert_stop_actor_reason_v3_to_v2(x: v3::StopActorReason) -> Result { + Ok(match x { + v3::StopActorReason::SleepIntent => v2::StopActorReason::SleepIntent, + v3::StopActorReason::StopIntent => v2::StopActorReason::StopIntent, + v3::StopActorReason::Destroy => v2::StopActorReason::Destroy, + v3::StopActorReason::GoingAway => v2::StopActorReason::GoingAway, + v3::StopActorReason::Lost => v2::StopActorReason::Lost, + }) +} + +pub fn convert_command_stop_actor_v3_to_v2( + x: v3::CommandStopActor, +) -> Result { + Ok(v2::CommandStopActor { + reason: convert_stop_actor_reason_v3_to_v2(x.reason)?, + }) +} + +pub fn convert_command_v3_to_v2(x: v3::Command) -> Result { + Ok(match x { + v3::Command::CommandStartActor(v) => { + v2::Command::CommandStartActor(convert_command_start_actor_v3_to_v2(v)?) + } + v3::Command::CommandStopActor(v) => { + v2::Command::CommandStopActor(convert_command_stop_actor_v3_to_v2(v)?) + } + }) +} + +pub fn convert_command_wrapper_v3_to_v2(x: v3::CommandWrapper) -> Result { + Ok(v2::CommandWrapper { + checkpoint: convert_actor_checkpoint_v3_to_v2(x.checkpoint)?, + inner: convert_command_v3_to_v2(x.inner)?, + }) +} + +pub fn convert_actor_command_key_data_v3_to_v2( + x: v3::ActorCommandKeyData, +) -> Result { + Ok(match x { + v3::ActorCommandKeyData::CommandStartActor(v) => { + v2::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v3_to_v2(v)?) + } + v3::ActorCommandKeyData::CommandStopActor(v) => { + v2::ActorCommandKeyData::CommandStopActor(convert_command_stop_actor_v3_to_v2(v)?) + } + }) +} + +pub fn convert_message_id_v3_to_v2(x: v3::MessageId) -> Result { + Ok(v2::MessageId { + gateway_id: x.gateway_id, + request_id: x.request_id, + message_index: x.message_index, + }) +} + +pub fn convert_to_envoy_request_start_v3_to_v2( + x: v3::ToEnvoyRequestStart, +) -> Result { + Ok(v2::ToEnvoyRequestStart { + actor_id: x.actor_id, + method: x.method, + path: x.path, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_envoy_request_chunk_v3_to_v2( + x: v3::ToEnvoyRequestChunk, +) -> Result { + Ok(v2::ToEnvoyRequestChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_rivet_response_start_v3_to_v2( + x: v3::ToRivetResponseStart, +) -> Result { + Ok(v2::ToRivetResponseStart { + status: x.status, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_rivet_response_chunk_v3_to_v2( + x: v3::ToRivetResponseChunk, +) -> Result { + Ok(v2::ToRivetResponseChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_envoy_web_socket_open_v3_to_v2( + x: v3::ToEnvoyWebSocketOpen, +) -> Result { + Ok(v2::ToEnvoyWebSocketOpen { + actor_id: x.actor_id, + path: x.path, + headers: x.headers, + }) +} + +pub fn convert_to_envoy_web_socket_message_v3_to_v2( + x: v3::ToEnvoyWebSocketMessage, +) -> Result { + Ok(v2::ToEnvoyWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_envoy_web_socket_close_v3_to_v2( + x: v3::ToEnvoyWebSocketClose, +) -> Result { + Ok(v2::ToEnvoyWebSocketClose { + code: x.code, + reason: x.reason, + }) +} + +pub fn convert_to_rivet_web_socket_open_v3_to_v2( + x: v3::ToRivetWebSocketOpen, +) -> Result { + Ok(v2::ToRivetWebSocketOpen { + can_hibernate: x.can_hibernate, + }) +} + +pub fn convert_to_rivet_web_socket_message_v3_to_v2( + x: v3::ToRivetWebSocketMessage, +) -> Result { + Ok(v2::ToRivetWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_rivet_web_socket_message_ack_v3_to_v2( + x: v3::ToRivetWebSocketMessageAck, +) -> Result { + Ok(v2::ToRivetWebSocketMessageAck { index: x.index }) +} + +pub fn convert_to_rivet_web_socket_close_v3_to_v2( + x: v3::ToRivetWebSocketClose, +) -> Result { + Ok(v2::ToRivetWebSocketClose { + code: x.code, + reason: x.reason, + hibernate: x.hibernate, + }) +} + +pub fn convert_to_rivet_tunnel_message_kind_v3_to_v2( + x: v3::ToRivetTunnelMessageKind, +) -> Result { + Ok(match x { + v3::ToRivetTunnelMessageKind::ToRivetResponseStart(v) => { + v2::ToRivetTunnelMessageKind::ToRivetResponseStart( + convert_to_rivet_response_start_v3_to_v2(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetResponseChunk(v) => { + v2::ToRivetTunnelMessageKind::ToRivetResponseChunk( + convert_to_rivet_response_chunk_v3_to_v2(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetResponseAbort => { + v2::ToRivetTunnelMessageKind::ToRivetResponseAbort + } + v3::ToRivetTunnelMessageKind::ToRivetWebSocketOpen(v) => { + v2::ToRivetTunnelMessageKind::ToRivetWebSocketOpen( + convert_to_rivet_web_socket_open_v3_to_v2(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetWebSocketMessage(v) => { + v2::ToRivetTunnelMessageKind::ToRivetWebSocketMessage( + convert_to_rivet_web_socket_message_v3_to_v2(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck(v) => { + v2::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck( + convert_to_rivet_web_socket_message_ack_v3_to_v2(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetWebSocketClose(v) => { + v2::ToRivetTunnelMessageKind::ToRivetWebSocketClose( + convert_to_rivet_web_socket_close_v3_to_v2(v)?, + ) + } + }) +} + +pub fn convert_to_rivet_tunnel_message_v3_to_v2( + x: v3::ToRivetTunnelMessage, +) -> Result { + Ok(v2::ToRivetTunnelMessage { + message_id: convert_message_id_v3_to_v2(x.message_id)?, + message_kind: convert_to_rivet_tunnel_message_kind_v3_to_v2(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_tunnel_message_kind_v3_to_v2( + x: v3::ToEnvoyTunnelMessageKind, +) -> Result { + Ok(match x { + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart( + convert_to_envoy_request_start_v3_to_v2(v)?, + ) + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk( + convert_to_envoy_request_chunk_v3_to_v2(v)?, + ) + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen( + convert_to_envoy_web_socket_open_v3_to_v2(v)?, + ) + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage( + convert_to_envoy_web_socket_message_v3_to_v2(v)?, + ) + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose(v) => { + v2::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose( + convert_to_envoy_web_socket_close_v3_to_v2(v)?, + ) + } + }) +} + +pub fn convert_to_envoy_tunnel_message_v3_to_v2( + x: v3::ToEnvoyTunnelMessage, +) -> Result { + Ok(v2::ToEnvoyTunnelMessage { + message_id: convert_message_id_v3_to_v2(x.message_id)?, + message_kind: convert_to_envoy_tunnel_message_kind_v3_to_v2(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_ping_v3_to_v2(x: v3::ToEnvoyPing) -> Result { + Ok(v2::ToEnvoyPing { ts: x.ts }) +} + +pub fn convert_to_rivet_metadata_v3_to_v2(x: v3::ToRivetMetadata) -> Result { + Ok(v2::ToRivetMetadata { + prepopulate_actor_names: x + .prepopulate_actor_names + .map(|v| { + v.into_iter() + .map(|(k, v)| -> Result<_> { Ok((k, convert_actor_name_v3_to_v2(v)?)) }) + .collect::>() + }) + .transpose()?, + metadata: x.metadata, + }) +} + +pub fn convert_to_rivet_events_v3_to_v2(x: v3::ToRivetEvents) -> Result { + Ok(x.into_iter() + .map(|v| convert_event_wrapper_v3_to_v2(v)) + .collect::>>()?) +} + +pub fn convert_to_rivet_ack_commands_v3_to_v2( + x: v3::ToRivetAckCommands, +) -> Result { + Ok(v2::ToRivetAckCommands { + last_command_checkpoints: x + .last_command_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v3_to_v2(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_rivet_pong_v3_to_v2(x: v3::ToRivetPong) -> Result { + Ok(v2::ToRivetPong { ts: x.ts }) +} + +pub fn convert_to_rivet_kv_request_v3_to_v2( + x: v3::ToRivetKvRequest, +) -> Result { + Ok(v2::ToRivetKvRequest { + actor_id: x.actor_id, + request_id: x.request_id, + data: convert_kv_request_data_v3_to_v2(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_get_pages_request_v3_to_v2( + x: v3::ToRivetSqliteGetPagesRequest, +) -> Result { + Ok(v2::ToRivetSqliteGetPagesRequest { + request_id: x.request_id, + data: convert_sqlite_get_pages_request_v3_to_v2(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_commit_request_v3_to_v2( + x: v3::ToRivetSqliteCommitRequest, +) -> Result { + Ok(v2::ToRivetSqliteCommitRequest { + request_id: x.request_id, + data: convert_sqlite_commit_request_v3_to_v2(x.data)?, + }) +} + +pub fn convert_to_rivet_v3_to_v2(x: v3::ToRivet) -> Result { + Ok(match x { + v3::ToRivet::ToRivetMetadata(v) => { + v2::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v3_to_v2(v)?) + } + v3::ToRivet::ToRivetEvents(v) => { + v2::ToRivet::ToRivetEvents(convert_to_rivet_events_v3_to_v2(v)?) + } + v3::ToRivet::ToRivetAckCommands(v) => { + v2::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v3_to_v2(v)?) + } + v3::ToRivet::ToRivetStopping => v2::ToRivet::ToRivetStopping, + v3::ToRivet::ToRivetPong(v) => v2::ToRivet::ToRivetPong(convert_to_rivet_pong_v3_to_v2(v)?), + v3::ToRivet::ToRivetKvRequest(v) => { + v2::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v3_to_v2(v)?) + } + v3::ToRivet::ToRivetTunnelMessage(v) => { + v2::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v3_to_v2(v)?) + } + v3::ToRivet::ToRivetSqliteGetPagesRequest(_) + | v3::ToRivet::ToRivetSqliteCommitRequest(_) => { + bail!("stateless sqlite requests require envoy-protocol v3") + } + }) +} + +pub fn convert_protocol_metadata_v3_to_v2(x: v3::ProtocolMetadata) -> Result { + Ok(v2::ProtocolMetadata { + envoy_lost_threshold: x.envoy_lost_threshold, + actor_stop_threshold: x.actor_stop_threshold, + max_response_payload_size: x.max_response_payload_size, + }) +} + +pub fn convert_to_envoy_init_v3_to_v2(x: v3::ToEnvoyInit) -> Result { + Ok(v2::ToEnvoyInit { + metadata: convert_protocol_metadata_v3_to_v2(x.metadata)?, + }) +} + +pub fn convert_to_envoy_commands_v3_to_v2(x: v3::ToEnvoyCommands) -> Result { + Ok(x.into_iter() + .map(|v| convert_command_wrapper_v3_to_v2(v)) + .collect::>>()?) +} + +pub fn convert_to_envoy_ack_events_v3_to_v2( + x: v3::ToEnvoyAckEvents, +) -> Result { + Ok(v2::ToEnvoyAckEvents { + last_event_checkpoints: x + .last_event_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v3_to_v2(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_envoy_kv_response_v3_to_v2( + x: v3::ToEnvoyKvResponse, +) -> Result { + Ok(v2::ToEnvoyKvResponse { + request_id: x.request_id, + data: convert_kv_response_data_v3_to_v2(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_get_pages_response_v3_to_v2( + x: v3::ToEnvoySqliteGetPagesResponse, +) -> Result { + Ok(v2::ToEnvoySqliteGetPagesResponse { + request_id: x.request_id, + data: convert_sqlite_get_pages_response_v3_to_v2(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_commit_response_v3_to_v2( + x: v3::ToEnvoySqliteCommitResponse, +) -> Result { + Ok(v2::ToEnvoySqliteCommitResponse { + request_id: x.request_id, + data: convert_sqlite_commit_response_v3_to_v2(x.data)?, + }) +} + +pub fn convert_to_envoy_v3_to_v2(x: v3::ToEnvoy) -> Result { + Ok(match x { + v3::ToEnvoy::ToEnvoyInit(v) => v2::ToEnvoy::ToEnvoyInit(convert_to_envoy_init_v3_to_v2(v)?), + v3::ToEnvoy::ToEnvoyCommands(v) => { + v2::ToEnvoy::ToEnvoyCommands(convert_to_envoy_commands_v3_to_v2(v)?) + } + v3::ToEnvoy::ToEnvoyAckEvents(v) => { + v2::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v3_to_v2(v)?) + } + v3::ToEnvoy::ToEnvoyKvResponse(v) => { + v2::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v3_to_v2(v)?) + } + v3::ToEnvoy::ToEnvoyTunnelMessage(v) => { + v2::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v3_to_v2(v)?) + } + v3::ToEnvoy::ToEnvoyPing(v) => v2::ToEnvoy::ToEnvoyPing(convert_to_envoy_ping_v3_to_v2(v)?), + v3::ToEnvoy::ToEnvoySqliteGetPagesResponse(_) + | v3::ToEnvoy::ToEnvoySqliteCommitResponse(_) => { + bail!("stateless sqlite responses require envoy-protocol v3") + } + }) +} + +pub fn convert_to_envoy_conn_ping_v3_to_v2(x: v3::ToEnvoyConnPing) -> Result { + Ok(v2::ToEnvoyConnPing { + gateway_id: x.gateway_id, + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_envoy_conn_v3_to_v2(x: v3::ToEnvoyConn) -> Result { + Ok(match x { + v3::ToEnvoyConn::ToEnvoyConnPing(v) => { + v2::ToEnvoyConn::ToEnvoyConnPing(convert_to_envoy_conn_ping_v3_to_v2(v)?) + } + v3::ToEnvoyConn::ToEnvoyConnClose => v2::ToEnvoyConn::ToEnvoyConnClose, + v3::ToEnvoyConn::ToEnvoyCommands(v) => { + v2::ToEnvoyConn::ToEnvoyCommands(convert_to_envoy_commands_v3_to_v2(v)?) + } + v3::ToEnvoyConn::ToEnvoyAckEvents(v) => { + v2::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v3_to_v2(v)?) + } + v3::ToEnvoyConn::ToEnvoyTunnelMessage(v) => { + v2::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v3_to_v2(v)?) + } + }) +} + +pub fn convert_to_gateway_pong_v3_to_v2(x: v3::ToGatewayPong) -> Result { + Ok(v2::ToGatewayPong { + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_gateway_v3_to_v2(x: v3::ToGateway) -> Result { + Ok(match x { + v3::ToGateway::ToGatewayPong(v) => { + v2::ToGateway::ToGatewayPong(convert_to_gateway_pong_v3_to_v2(v)?) + } + v3::ToGateway::ToRivetTunnelMessage(v) => { + v2::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v3_to_v2(v)?) + } + }) +} + +pub fn convert_to_outbound_actor_start_v3_to_v2( + x: v3::ToOutboundActorStart, +) -> Result { + Ok(v2::ToOutboundActorStart { + namespace_id: x.namespace_id, + pool_name: x.pool_name, + checkpoint: convert_actor_checkpoint_v3_to_v2(x.checkpoint)?, + actor_config: convert_actor_config_v3_to_v2(x.actor_config)?, + }) +} + +pub fn convert_to_outbound_v3_to_v2(x: v3::ToOutbound) -> Result { + Ok(match x { + v3::ToOutbound::ToOutboundActorStart(v) => { + v2::ToOutbound::ToOutboundActorStart(convert_to_outbound_actor_start_v3_to_v2(v)?) + } + }) +} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned/v3_to_v4.rs b/engine/sdks/rust/envoy-protocol/src/versioned/v3_to_v4.rs new file mode 100644 index 0000000000..224a0abe90 --- /dev/null +++ b/engine/sdks/rust/envoy-protocol/src/versioned/v3_to_v4.rs @@ -0,0 +1,878 @@ +// @generated initial scaffold by scripts/vbare-gen-converters +// from: v3.bare, to: v4.bare +// Replace each todo!() with the migration semantics, then drop the @generated marker. + +#![allow(dead_code, unused_variables)] + +use anyhow::Result; + +use crate::generated::{v3, v4}; + +pub fn convert_kv_metadata_v3_to_v4(x: v3::KvMetadata) -> Result { + Ok(v4::KvMetadata { + version: x.version, + update_ts: x.update_ts, + }) +} + +pub fn convert_kv_list_range_query_v3_to_v4( + x: v3::KvListRangeQuery, +) -> Result { + Ok(v4::KvListRangeQuery { + start: x.start, + end: x.end, + exclusive: x.exclusive, + }) +} + +pub fn convert_kv_list_prefix_query_v3_to_v4( + x: v3::KvListPrefixQuery, +) -> Result { + Ok(v4::KvListPrefixQuery { key: x.key }) +} + +pub fn convert_kv_list_query_v3_to_v4(x: v3::KvListQuery) -> Result { + Ok(match x { + v3::KvListQuery::KvListAllQuery => v4::KvListQuery::KvListAllQuery, + v3::KvListQuery::KvListRangeQuery(v) => { + v4::KvListQuery::KvListRangeQuery(convert_kv_list_range_query_v3_to_v4(v)?) + } + v3::KvListQuery::KvListPrefixQuery(v) => { + v4::KvListQuery::KvListPrefixQuery(convert_kv_list_prefix_query_v3_to_v4(v)?) + } + }) +} + +pub fn convert_kv_get_request_v3_to_v4(x: v3::KvGetRequest) -> Result { + Ok(v4::KvGetRequest { keys: x.keys }) +} + +pub fn convert_kv_list_request_v3_to_v4(x: v3::KvListRequest) -> Result { + Ok(v4::KvListRequest { + query: convert_kv_list_query_v3_to_v4(x.query)?, + reverse: x.reverse, + limit: x.limit, + }) +} + +pub fn convert_kv_put_request_v3_to_v4(x: v3::KvPutRequest) -> Result { + Ok(v4::KvPutRequest { + keys: x.keys, + values: x.values, + }) +} + +pub fn convert_kv_delete_request_v3_to_v4(x: v3::KvDeleteRequest) -> Result { + Ok(v4::KvDeleteRequest { keys: x.keys }) +} + +pub fn convert_kv_delete_range_request_v3_to_v4( + x: v3::KvDeleteRangeRequest, +) -> Result { + Ok(v4::KvDeleteRangeRequest { + start: x.start, + end: x.end, + }) +} + +pub fn convert_kv_error_response_v3_to_v4(x: v3::KvErrorResponse) -> Result { + Ok(v4::KvErrorResponse { message: x.message }) +} + +pub fn convert_kv_get_response_v3_to_v4(x: v3::KvGetResponse) -> Result { + Ok(v4::KvGetResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v3_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_list_response_v3_to_v4(x: v3::KvListResponse) -> Result { + Ok(v4::KvListResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v3_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_request_data_v3_to_v4(x: v3::KvRequestData) -> Result { + Ok(match x { + v3::KvRequestData::KvGetRequest(v) => { + v4::KvRequestData::KvGetRequest(convert_kv_get_request_v3_to_v4(v)?) + } + v3::KvRequestData::KvListRequest(v) => { + v4::KvRequestData::KvListRequest(convert_kv_list_request_v3_to_v4(v)?) + } + v3::KvRequestData::KvPutRequest(v) => { + v4::KvRequestData::KvPutRequest(convert_kv_put_request_v3_to_v4(v)?) + } + v3::KvRequestData::KvDeleteRequest(v) => { + v4::KvRequestData::KvDeleteRequest(convert_kv_delete_request_v3_to_v4(v)?) + } + v3::KvRequestData::KvDeleteRangeRequest(v) => { + v4::KvRequestData::KvDeleteRangeRequest(convert_kv_delete_range_request_v3_to_v4(v)?) + } + v3::KvRequestData::KvDropRequest => v4::KvRequestData::KvDropRequest, + }) +} + +pub fn convert_kv_response_data_v3_to_v4(x: v3::KvResponseData) -> Result { + Ok(match x { + v3::KvResponseData::KvErrorResponse(v) => { + v4::KvResponseData::KvErrorResponse(convert_kv_error_response_v3_to_v4(v)?) + } + v3::KvResponseData::KvGetResponse(v) => { + v4::KvResponseData::KvGetResponse(convert_kv_get_response_v3_to_v4(v)?) + } + v3::KvResponseData::KvListResponse(v) => { + v4::KvResponseData::KvListResponse(convert_kv_list_response_v3_to_v4(v)?) + } + v3::KvResponseData::KvPutResponse => v4::KvResponseData::KvPutResponse, + v3::KvResponseData::KvDeleteResponse => v4::KvResponseData::KvDeleteResponse, + v3::KvResponseData::KvDropResponse => v4::KvResponseData::KvDropResponse, + }) +} + +pub fn convert_sqlite_dirty_page_v3_to_v4(x: v3::SqliteDirtyPage) -> Result { + Ok(v4::SqliteDirtyPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_fetched_page_v3_to_v4( + x: v3::SqliteFetchedPage, +) -> Result { + Ok(v4::SqliteFetchedPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_get_pages_request_v3_to_v4( + x: v3::SqliteGetPagesRequest, +) -> Result { + Ok(v4::SqliteGetPagesRequest { + actor_id: x.actor_id, + pgnos: x.pgnos, + expected_generation: x.expected_generation, + expected_head_txid: x.expected_head_txid, + }) +} + +pub fn convert_sqlite_get_pages_ok_v3_to_v4( + x: v3::SqliteGetPagesOk, +) -> Result { + Ok(v4::SqliteGetPagesOk { + pages: x + .pages + .into_iter() + .map(|v| convert_sqlite_fetched_page_v3_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_sqlite_error_response_v3_to_v4( + x: v3::SqliteErrorResponse, +) -> Result { + Ok(v4::SqliteErrorResponse { message: x.message }) +} + +pub fn convert_sqlite_get_pages_response_v3_to_v4( + x: v3::SqliteGetPagesResponse, +) -> Result { + Ok(match x { + v3::SqliteGetPagesResponse::SqliteGetPagesOk(v) => { + v4::SqliteGetPagesResponse::SqliteGetPagesOk(convert_sqlite_get_pages_ok_v3_to_v4(v)?) + } + v3::SqliteGetPagesResponse::SqliteErrorResponse(v) => { + v4::SqliteGetPagesResponse::SqliteErrorResponse(convert_sqlite_error_response_v3_to_v4( + v, + )?) + } + }) +} + +pub fn convert_sqlite_commit_request_v3_to_v4( + x: v3::SqliteCommitRequest, +) -> Result { + Ok(v4::SqliteCommitRequest { + actor_id: x.actor_id, + dirty_pages: x + .dirty_pages + .into_iter() + .map(|v| convert_sqlite_dirty_page_v3_to_v4(v)) + .collect::>>()?, + db_size_pages: x.db_size_pages, + now_ms: x.now_ms, + expected_generation: x.expected_generation, + expected_head_txid: x.expected_head_txid, + }) +} + +pub fn convert_sqlite_commit_response_v3_to_v4( + x: v3::SqliteCommitResponse, +) -> Result { + Ok(match x { + v3::SqliteCommitResponse::SqliteCommitOk => v4::SqliteCommitResponse::SqliteCommitOk, + v3::SqliteCommitResponse::SqliteErrorResponse(v) => { + v4::SqliteCommitResponse::SqliteErrorResponse(convert_sqlite_error_response_v3_to_v4( + v, + )?) + } + }) +} + +pub fn convert_stop_code_v3_to_v4(x: v3::StopCode) -> Result { + Ok(match x { + v3::StopCode::Ok => v4::StopCode::Ok, + v3::StopCode::Error => v4::StopCode::Error, + }) +} + +pub fn convert_actor_name_v3_to_v4(x: v3::ActorName) -> Result { + Ok(v4::ActorName { + metadata: x.metadata, + }) +} + +pub fn convert_actor_config_v3_to_v4(x: v3::ActorConfig) -> Result { + Ok(v4::ActorConfig { + name: x.name, + key: x.key, + create_ts: x.create_ts, + input: x.input, + }) +} + +pub fn convert_actor_checkpoint_v3_to_v4(x: v3::ActorCheckpoint) -> Result { + Ok(v4::ActorCheckpoint { + actor_id: x.actor_id, + generation: x.generation, + index: x.index, + }) +} + +pub fn convert_actor_intent_v3_to_v4(x: v3::ActorIntent) -> Result { + Ok(match x { + v3::ActorIntent::ActorIntentSleep => v4::ActorIntent::ActorIntentSleep, + v3::ActorIntent::ActorIntentStop => v4::ActorIntent::ActorIntentStop, + }) +} + +pub fn convert_actor_state_stopped_v3_to_v4( + x: v3::ActorStateStopped, +) -> Result { + Ok(v4::ActorStateStopped { + code: convert_stop_code_v3_to_v4(x.code)?, + message: x.message, + }) +} + +pub fn convert_actor_state_v3_to_v4(x: v3::ActorState) -> Result { + Ok(match x { + v3::ActorState::ActorStateRunning => v4::ActorState::ActorStateRunning, + v3::ActorState::ActorStateStopped(v) => { + v4::ActorState::ActorStateStopped(convert_actor_state_stopped_v3_to_v4(v)?) + } + }) +} + +pub fn convert_event_actor_intent_v3_to_v4( + x: v3::EventActorIntent, +) -> Result { + Ok(v4::EventActorIntent { + intent: convert_actor_intent_v3_to_v4(x.intent)?, + }) +} + +pub fn convert_event_actor_state_update_v3_to_v4( + x: v3::EventActorStateUpdate, +) -> Result { + Ok(v4::EventActorStateUpdate { + state: convert_actor_state_v3_to_v4(x.state)?, + }) +} + +pub fn convert_event_actor_set_alarm_v3_to_v4( + x: v3::EventActorSetAlarm, +) -> Result { + Ok(v4::EventActorSetAlarm { + alarm_ts: x.alarm_ts, + }) +} + +pub fn convert_event_v3_to_v4(x: v3::Event) -> Result { + Ok(match x { + v3::Event::EventActorIntent(v) => { + v4::Event::EventActorIntent(convert_event_actor_intent_v3_to_v4(v)?) + } + v3::Event::EventActorStateUpdate(v) => { + v4::Event::EventActorStateUpdate(convert_event_actor_state_update_v3_to_v4(v)?) + } + v3::Event::EventActorSetAlarm(v) => { + v4::Event::EventActorSetAlarm(convert_event_actor_set_alarm_v3_to_v4(v)?) + } + }) +} + +pub fn convert_event_wrapper_v3_to_v4(x: v3::EventWrapper) -> Result { + Ok(v4::EventWrapper { + checkpoint: convert_actor_checkpoint_v3_to_v4(x.checkpoint)?, + inner: convert_event_v3_to_v4(x.inner)?, + }) +} + +pub fn convert_preloaded_kv_entry_v3_to_v4( + x: v3::PreloadedKvEntry, +) -> Result { + Ok(v4::PreloadedKvEntry { + key: x.key, + value: x.value, + metadata: convert_kv_metadata_v3_to_v4(x.metadata)?, + }) +} + +pub fn convert_preloaded_kv_v3_to_v4(x: v3::PreloadedKv) -> Result { + Ok(v4::PreloadedKv { + entries: x + .entries + .into_iter() + .map(|v| convert_preloaded_kv_entry_v3_to_v4(v)) + .collect::>>()?, + requested_get_keys: x.requested_get_keys, + requested_prefixes: x.requested_prefixes, + }) +} + +pub fn convert_hibernating_request_v3_to_v4( + x: v3::HibernatingRequest, +) -> Result { + Ok(v4::HibernatingRequest { + gateway_id: x.gateway_id, + request_id: x.request_id, + }) +} + +pub fn convert_command_start_actor_v3_to_v4( + x: v3::CommandStartActor, +) -> Result { + Ok(v4::CommandStartActor { + config: convert_actor_config_v3_to_v4(x.config)?, + hibernating_requests: x + .hibernating_requests + .into_iter() + .map(|v| convert_hibernating_request_v3_to_v4(v)) + .collect::>>()?, + preloaded_kv: x + .preloaded_kv + .map(|v| convert_preloaded_kv_v3_to_v4(v)) + .transpose()?, + }) +} + +pub fn convert_stop_actor_reason_v3_to_v4(x: v3::StopActorReason) -> Result { + Ok(match x { + v3::StopActorReason::SleepIntent => v4::StopActorReason::SleepIntent, + v3::StopActorReason::StopIntent => v4::StopActorReason::StopIntent, + v3::StopActorReason::Destroy => v4::StopActorReason::Destroy, + v3::StopActorReason::GoingAway => v4::StopActorReason::GoingAway, + v3::StopActorReason::Lost => v4::StopActorReason::Lost, + }) +} + +pub fn convert_command_stop_actor_v3_to_v4( + x: v3::CommandStopActor, +) -> Result { + Ok(v4::CommandStopActor { + reason: convert_stop_actor_reason_v3_to_v4(x.reason)?, + }) +} + +pub fn convert_command_v3_to_v4(x: v3::Command) -> Result { + Ok(match x { + v3::Command::CommandStartActor(v) => { + v4::Command::CommandStartActor(convert_command_start_actor_v3_to_v4(v)?) + } + v3::Command::CommandStopActor(v) => { + v4::Command::CommandStopActor(convert_command_stop_actor_v3_to_v4(v)?) + } + }) +} + +pub fn convert_command_wrapper_v3_to_v4(x: v3::CommandWrapper) -> Result { + Ok(v4::CommandWrapper { + checkpoint: convert_actor_checkpoint_v3_to_v4(x.checkpoint)?, + inner: convert_command_v3_to_v4(x.inner)?, + }) +} + +pub fn convert_actor_command_key_data_v3_to_v4( + x: v3::ActorCommandKeyData, +) -> Result { + Ok(match x { + v3::ActorCommandKeyData::CommandStartActor(v) => { + v4::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v3_to_v4(v)?) + } + v3::ActorCommandKeyData::CommandStopActor(v) => { + v4::ActorCommandKeyData::CommandStopActor(convert_command_stop_actor_v3_to_v4(v)?) + } + }) +} + +pub fn convert_message_id_v3_to_v4(x: v3::MessageId) -> Result { + Ok(v4::MessageId { + gateway_id: x.gateway_id, + request_id: x.request_id, + message_index: x.message_index, + }) +} + +pub fn convert_to_envoy_request_start_v3_to_v4( + x: v3::ToEnvoyRequestStart, +) -> Result { + Ok(v4::ToEnvoyRequestStart { + actor_id: x.actor_id, + method: x.method, + path: x.path, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_envoy_request_chunk_v3_to_v4( + x: v3::ToEnvoyRequestChunk, +) -> Result { + Ok(v4::ToEnvoyRequestChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_rivet_response_start_v3_to_v4( + x: v3::ToRivetResponseStart, +) -> Result { + Ok(v4::ToRivetResponseStart { + status: x.status, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_rivet_response_chunk_v3_to_v4( + x: v3::ToRivetResponseChunk, +) -> Result { + Ok(v4::ToRivetResponseChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_envoy_web_socket_open_v3_to_v4( + x: v3::ToEnvoyWebSocketOpen, +) -> Result { + Ok(v4::ToEnvoyWebSocketOpen { + actor_id: x.actor_id, + path: x.path, + headers: x.headers, + }) +} + +pub fn convert_to_envoy_web_socket_message_v3_to_v4( + x: v3::ToEnvoyWebSocketMessage, +) -> Result { + Ok(v4::ToEnvoyWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_envoy_web_socket_close_v3_to_v4( + x: v3::ToEnvoyWebSocketClose, +) -> Result { + Ok(v4::ToEnvoyWebSocketClose { + code: x.code, + reason: x.reason, + }) +} + +pub fn convert_to_rivet_web_socket_open_v3_to_v4( + x: v3::ToRivetWebSocketOpen, +) -> Result { + Ok(v4::ToRivetWebSocketOpen { + can_hibernate: x.can_hibernate, + }) +} + +pub fn convert_to_rivet_web_socket_message_v3_to_v4( + x: v3::ToRivetWebSocketMessage, +) -> Result { + Ok(v4::ToRivetWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_rivet_web_socket_message_ack_v3_to_v4( + x: v3::ToRivetWebSocketMessageAck, +) -> Result { + Ok(v4::ToRivetWebSocketMessageAck { index: x.index }) +} + +pub fn convert_to_rivet_web_socket_close_v3_to_v4( + x: v3::ToRivetWebSocketClose, +) -> Result { + Ok(v4::ToRivetWebSocketClose { + code: x.code, + reason: x.reason, + hibernate: x.hibernate, + }) +} + +pub fn convert_to_rivet_tunnel_message_kind_v3_to_v4( + x: v3::ToRivetTunnelMessageKind, +) -> Result { + Ok(match x { + v3::ToRivetTunnelMessageKind::ToRivetResponseStart(v) => { + v4::ToRivetTunnelMessageKind::ToRivetResponseStart( + convert_to_rivet_response_start_v3_to_v4(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetResponseChunk(v) => { + v4::ToRivetTunnelMessageKind::ToRivetResponseChunk( + convert_to_rivet_response_chunk_v3_to_v4(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetResponseAbort => { + v4::ToRivetTunnelMessageKind::ToRivetResponseAbort + } + v3::ToRivetTunnelMessageKind::ToRivetWebSocketOpen(v) => { + v4::ToRivetTunnelMessageKind::ToRivetWebSocketOpen( + convert_to_rivet_web_socket_open_v3_to_v4(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetWebSocketMessage(v) => { + v4::ToRivetTunnelMessageKind::ToRivetWebSocketMessage( + convert_to_rivet_web_socket_message_v3_to_v4(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck(v) => { + v4::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck( + convert_to_rivet_web_socket_message_ack_v3_to_v4(v)?, + ) + } + v3::ToRivetTunnelMessageKind::ToRivetWebSocketClose(v) => { + v4::ToRivetTunnelMessageKind::ToRivetWebSocketClose( + convert_to_rivet_web_socket_close_v3_to_v4(v)?, + ) + } + }) +} + +pub fn convert_to_rivet_tunnel_message_v3_to_v4( + x: v3::ToRivetTunnelMessage, +) -> Result { + Ok(v4::ToRivetTunnelMessage { + message_id: convert_message_id_v3_to_v4(x.message_id)?, + message_kind: convert_to_rivet_tunnel_message_kind_v3_to_v4(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_tunnel_message_kind_v3_to_v4( + x: v3::ToEnvoyTunnelMessageKind, +) -> Result { + Ok(match x { + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart( + convert_to_envoy_request_start_v3_to_v4(v)?, + ) + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk( + convert_to_envoy_request_chunk_v3_to_v4(v)?, + ) + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen( + convert_to_envoy_web_socket_open_v3_to_v4(v)?, + ) + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage( + convert_to_envoy_web_socket_message_v3_to_v4(v)?, + ) + } + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose( + convert_to_envoy_web_socket_close_v3_to_v4(v)?, + ) + } + }) +} + +pub fn convert_to_envoy_tunnel_message_v3_to_v4( + x: v3::ToEnvoyTunnelMessage, +) -> Result { + Ok(v4::ToEnvoyTunnelMessage { + message_id: convert_message_id_v3_to_v4(x.message_id)?, + message_kind: convert_to_envoy_tunnel_message_kind_v3_to_v4(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_ping_v3_to_v4(x: v3::ToEnvoyPing) -> Result { + Ok(v4::ToEnvoyPing { ts: x.ts }) +} + +pub fn convert_to_rivet_metadata_v3_to_v4(x: v3::ToRivetMetadata) -> Result { + Ok(v4::ToRivetMetadata { + prepopulate_actor_names: x + .prepopulate_actor_names + .map(|v| { + v.into_iter() + .map(|(k, v)| -> Result<_> { Ok((k, convert_actor_name_v3_to_v4(v)?)) }) + .collect::>() + }) + .transpose()?, + metadata: x.metadata, + }) +} + +pub fn convert_to_rivet_events_v3_to_v4(x: v3::ToRivetEvents) -> Result { + Ok(x.into_iter() + .map(|v| convert_event_wrapper_v3_to_v4(v)) + .collect::>>()?) +} + +pub fn convert_to_rivet_ack_commands_v3_to_v4( + x: v3::ToRivetAckCommands, +) -> Result { + Ok(v4::ToRivetAckCommands { + last_command_checkpoints: x + .last_command_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v3_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_rivet_pong_v3_to_v4(x: v3::ToRivetPong) -> Result { + Ok(v4::ToRivetPong { ts: x.ts }) +} + +pub fn convert_to_rivet_kv_request_v3_to_v4( + x: v3::ToRivetKvRequest, +) -> Result { + Ok(v4::ToRivetKvRequest { + actor_id: x.actor_id, + request_id: x.request_id, + data: convert_kv_request_data_v3_to_v4(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_get_pages_request_v3_to_v4( + x: v3::ToRivetSqliteGetPagesRequest, +) -> Result { + Ok(v4::ToRivetSqliteGetPagesRequest { + request_id: x.request_id, + data: convert_sqlite_get_pages_request_v3_to_v4(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_commit_request_v3_to_v4( + x: v3::ToRivetSqliteCommitRequest, +) -> Result { + Ok(v4::ToRivetSqliteCommitRequest { + request_id: x.request_id, + data: convert_sqlite_commit_request_v3_to_v4(x.data)?, + }) +} + +pub fn convert_to_rivet_v3_to_v4(x: v3::ToRivet) -> Result { + Ok(match x { + v3::ToRivet::ToRivetMetadata(v) => { + v4::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v3_to_v4(v)?) + } + v3::ToRivet::ToRivetEvents(v) => { + v4::ToRivet::ToRivetEvents(convert_to_rivet_events_v3_to_v4(v)?) + } + v3::ToRivet::ToRivetAckCommands(v) => { + v4::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v3_to_v4(v)?) + } + v3::ToRivet::ToRivetStopping => v4::ToRivet::ToRivetStopping, + v3::ToRivet::ToRivetPong(v) => v4::ToRivet::ToRivetPong(convert_to_rivet_pong_v3_to_v4(v)?), + v3::ToRivet::ToRivetKvRequest(v) => { + v4::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v3_to_v4(v)?) + } + v3::ToRivet::ToRivetTunnelMessage(v) => { + v4::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v3_to_v4(v)?) + } + v3::ToRivet::ToRivetSqliteGetPagesRequest(v) => v4::ToRivet::ToRivetSqliteGetPagesRequest( + convert_to_rivet_sqlite_get_pages_request_v3_to_v4(v)?, + ), + v3::ToRivet::ToRivetSqliteCommitRequest(v) => v4::ToRivet::ToRivetSqliteCommitRequest( + convert_to_rivet_sqlite_commit_request_v3_to_v4(v)?, + ), + }) +} + +pub fn convert_protocol_metadata_v3_to_v4(x: v3::ProtocolMetadata) -> Result { + Ok(v4::ProtocolMetadata { + envoy_lost_threshold: x.envoy_lost_threshold, + actor_stop_threshold: x.actor_stop_threshold, + max_response_payload_size: x.max_response_payload_size, + }) +} + +pub fn convert_to_envoy_init_v3_to_v4(x: v3::ToEnvoyInit) -> Result { + Ok(v4::ToEnvoyInit { + metadata: convert_protocol_metadata_v3_to_v4(x.metadata)?, + }) +} + +pub fn convert_to_envoy_commands_v3_to_v4(x: v3::ToEnvoyCommands) -> Result { + Ok(x.into_iter() + .map(|v| convert_command_wrapper_v3_to_v4(v)) + .collect::>>()?) +} + +pub fn convert_to_envoy_ack_events_v3_to_v4( + x: v3::ToEnvoyAckEvents, +) -> Result { + Ok(v4::ToEnvoyAckEvents { + last_event_checkpoints: x + .last_event_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v3_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_envoy_kv_response_v3_to_v4( + x: v3::ToEnvoyKvResponse, +) -> Result { + Ok(v4::ToEnvoyKvResponse { + request_id: x.request_id, + data: convert_kv_response_data_v3_to_v4(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_get_pages_response_v3_to_v4( + x: v3::ToEnvoySqliteGetPagesResponse, +) -> Result { + Ok(v4::ToEnvoySqliteGetPagesResponse { + request_id: x.request_id, + data: convert_sqlite_get_pages_response_v3_to_v4(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_commit_response_v3_to_v4( + x: v3::ToEnvoySqliteCommitResponse, +) -> Result { + Ok(v4::ToEnvoySqliteCommitResponse { + request_id: x.request_id, + data: convert_sqlite_commit_response_v3_to_v4(x.data)?, + }) +} + +pub fn convert_to_envoy_v3_to_v4(x: v3::ToEnvoy) -> Result { + Ok(match x { + v3::ToEnvoy::ToEnvoyInit(v) => v4::ToEnvoy::ToEnvoyInit(convert_to_envoy_init_v3_to_v4(v)?), + v3::ToEnvoy::ToEnvoyCommands(v) => { + v4::ToEnvoy::ToEnvoyCommands(convert_to_envoy_commands_v3_to_v4(v)?) + } + v3::ToEnvoy::ToEnvoyAckEvents(v) => { + v4::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v3_to_v4(v)?) + } + v3::ToEnvoy::ToEnvoyKvResponse(v) => { + v4::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v3_to_v4(v)?) + } + v3::ToEnvoy::ToEnvoyTunnelMessage(v) => { + v4::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v3_to_v4(v)?) + } + v3::ToEnvoy::ToEnvoyPing(v) => v4::ToEnvoy::ToEnvoyPing(convert_to_envoy_ping_v3_to_v4(v)?), + v3::ToEnvoy::ToEnvoySqliteGetPagesResponse(v) => { + v4::ToEnvoy::ToEnvoySqliteGetPagesResponse( + convert_to_envoy_sqlite_get_pages_response_v3_to_v4(v)?, + ) + } + v3::ToEnvoy::ToEnvoySqliteCommitResponse(v) => v4::ToEnvoy::ToEnvoySqliteCommitResponse( + convert_to_envoy_sqlite_commit_response_v3_to_v4(v)?, + ), + }) +} + +pub fn convert_to_envoy_conn_ping_v3_to_v4(x: v3::ToEnvoyConnPing) -> Result { + Ok(v4::ToEnvoyConnPing { + gateway_id: x.gateway_id, + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_envoy_conn_v3_to_v4(x: v3::ToEnvoyConn) -> Result { + Ok(match x { + v3::ToEnvoyConn::ToEnvoyConnPing(v) => { + v4::ToEnvoyConn::ToEnvoyConnPing(convert_to_envoy_conn_ping_v3_to_v4(v)?) + } + v3::ToEnvoyConn::ToEnvoyConnClose => v4::ToEnvoyConn::ToEnvoyConnClose, + v3::ToEnvoyConn::ToEnvoyCommands(v) => { + v4::ToEnvoyConn::ToEnvoyCommands(convert_to_envoy_commands_v3_to_v4(v)?) + } + v3::ToEnvoyConn::ToEnvoyAckEvents(v) => { + v4::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v3_to_v4(v)?) + } + v3::ToEnvoyConn::ToEnvoyTunnelMessage(v) => { + v4::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v3_to_v4(v)?) + } + }) +} + +pub fn convert_to_gateway_pong_v3_to_v4(x: v3::ToGatewayPong) -> Result { + Ok(v4::ToGatewayPong { + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_gateway_v3_to_v4(x: v3::ToGateway) -> Result { + Ok(match x { + v3::ToGateway::ToGatewayPong(v) => { + v4::ToGateway::ToGatewayPong(convert_to_gateway_pong_v3_to_v4(v)?) + } + v3::ToGateway::ToRivetTunnelMessage(v) => { + v4::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v3_to_v4(v)?) + } + }) +} + +pub fn convert_to_outbound_actor_start_v3_to_v4( + x: v3::ToOutboundActorStart, +) -> Result { + Ok(v4::ToOutboundActorStart { + namespace_id: x.namespace_id, + pool_name: x.pool_name, + checkpoint: convert_actor_checkpoint_v3_to_v4(x.checkpoint)?, + actor_config: convert_actor_config_v3_to_v4(x.actor_config)?, + }) +} + +pub fn convert_to_outbound_v3_to_v4(x: v3::ToOutbound) -> Result { + Ok(match x { + v3::ToOutbound::ToOutboundActorStart(v) => { + v4::ToOutbound::ToOutboundActorStart(convert_to_outbound_actor_start_v3_to_v4(v)?) + } + }) +} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned/v4_to_v3.rs b/engine/sdks/rust/envoy-protocol/src/versioned/v4_to_v3.rs new file mode 100644 index 0000000000..a8e5a5950e --- /dev/null +++ b/engine/sdks/rust/envoy-protocol/src/versioned/v4_to_v3.rs @@ -0,0 +1,898 @@ +// @generated initial scaffold by scripts/vbare-gen-converters +// from: v4.bare, to: v3.bare +// Replace each todo!() with the migration semantics, then drop the @generated marker. + +#![allow(dead_code, unused_variables)] + +use anyhow::Result; + +use crate::generated::{v3, v4}; +use crate::versioned::{ + ProtocolCompatibilityDirection, ProtocolCompatibilityFeature, incompatible, +}; + +pub fn convert_kv_metadata_v4_to_v3(x: v4::KvMetadata) -> Result { + Ok(v3::KvMetadata { + version: x.version, + update_ts: x.update_ts, + }) +} + +pub fn convert_kv_list_range_query_v4_to_v3( + x: v4::KvListRangeQuery, +) -> Result { + Ok(v3::KvListRangeQuery { + start: x.start, + end: x.end, + exclusive: x.exclusive, + }) +} + +pub fn convert_kv_list_prefix_query_v4_to_v3( + x: v4::KvListPrefixQuery, +) -> Result { + Ok(v3::KvListPrefixQuery { key: x.key }) +} + +pub fn convert_kv_list_query_v4_to_v3(x: v4::KvListQuery) -> Result { + Ok(match x { + v4::KvListQuery::KvListAllQuery => v3::KvListQuery::KvListAllQuery, + v4::KvListQuery::KvListRangeQuery(v) => { + v3::KvListQuery::KvListRangeQuery(convert_kv_list_range_query_v4_to_v3(v)?) + } + v4::KvListQuery::KvListPrefixQuery(v) => { + v3::KvListQuery::KvListPrefixQuery(convert_kv_list_prefix_query_v4_to_v3(v)?) + } + }) +} + +pub fn convert_kv_get_request_v4_to_v3(x: v4::KvGetRequest) -> Result { + Ok(v3::KvGetRequest { keys: x.keys }) +} + +pub fn convert_kv_list_request_v4_to_v3(x: v4::KvListRequest) -> Result { + Ok(v3::KvListRequest { + query: convert_kv_list_query_v4_to_v3(x.query)?, + reverse: x.reverse, + limit: x.limit, + }) +} + +pub fn convert_kv_put_request_v4_to_v3(x: v4::KvPutRequest) -> Result { + Ok(v3::KvPutRequest { + keys: x.keys, + values: x.values, + }) +} + +pub fn convert_kv_delete_request_v4_to_v3(x: v4::KvDeleteRequest) -> Result { + Ok(v3::KvDeleteRequest { keys: x.keys }) +} + +pub fn convert_kv_delete_range_request_v4_to_v3( + x: v4::KvDeleteRangeRequest, +) -> Result { + Ok(v3::KvDeleteRangeRequest { + start: x.start, + end: x.end, + }) +} + +pub fn convert_kv_error_response_v4_to_v3(x: v4::KvErrorResponse) -> Result { + Ok(v3::KvErrorResponse { message: x.message }) +} + +pub fn convert_kv_get_response_v4_to_v3(x: v4::KvGetResponse) -> Result { + Ok(v3::KvGetResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v4_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_list_response_v4_to_v3(x: v4::KvListResponse) -> Result { + Ok(v3::KvListResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v4_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_request_data_v4_to_v3(x: v4::KvRequestData) -> Result { + Ok(match x { + v4::KvRequestData::KvGetRequest(v) => { + v3::KvRequestData::KvGetRequest(convert_kv_get_request_v4_to_v3(v)?) + } + v4::KvRequestData::KvListRequest(v) => { + v3::KvRequestData::KvListRequest(convert_kv_list_request_v4_to_v3(v)?) + } + v4::KvRequestData::KvPutRequest(v) => { + v3::KvRequestData::KvPutRequest(convert_kv_put_request_v4_to_v3(v)?) + } + v4::KvRequestData::KvDeleteRequest(v) => { + v3::KvRequestData::KvDeleteRequest(convert_kv_delete_request_v4_to_v3(v)?) + } + v4::KvRequestData::KvDeleteRangeRequest(v) => { + v3::KvRequestData::KvDeleteRangeRequest(convert_kv_delete_range_request_v4_to_v3(v)?) + } + v4::KvRequestData::KvDropRequest => v3::KvRequestData::KvDropRequest, + }) +} + +pub fn convert_kv_response_data_v4_to_v3(x: v4::KvResponseData) -> Result { + Ok(match x { + v4::KvResponseData::KvErrorResponse(v) => { + v3::KvResponseData::KvErrorResponse(convert_kv_error_response_v4_to_v3(v)?) + } + v4::KvResponseData::KvGetResponse(v) => { + v3::KvResponseData::KvGetResponse(convert_kv_get_response_v4_to_v3(v)?) + } + v4::KvResponseData::KvListResponse(v) => { + v3::KvResponseData::KvListResponse(convert_kv_list_response_v4_to_v3(v)?) + } + v4::KvResponseData::KvPutResponse => v3::KvResponseData::KvPutResponse, + v4::KvResponseData::KvDeleteResponse => v3::KvResponseData::KvDeleteResponse, + v4::KvResponseData::KvDropResponse => v3::KvResponseData::KvDropResponse, + }) +} + +pub fn convert_sqlite_dirty_page_v4_to_v3(x: v4::SqliteDirtyPage) -> Result { + Ok(v3::SqliteDirtyPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_fetched_page_v4_to_v3( + x: v4::SqliteFetchedPage, +) -> Result { + Ok(v3::SqliteFetchedPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_get_pages_request_v4_to_v3( + x: v4::SqliteGetPagesRequest, +) -> Result { + Ok(v3::SqliteGetPagesRequest { + actor_id: x.actor_id, + pgnos: x.pgnos, + expected_generation: x.expected_generation, + expected_head_txid: x.expected_head_txid, + }) +} + +pub fn convert_sqlite_get_pages_ok_v4_to_v3( + x: v4::SqliteGetPagesOk, +) -> Result { + Ok(v3::SqliteGetPagesOk { + pages: x + .pages + .into_iter() + .map(|v| convert_sqlite_fetched_page_v4_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_sqlite_error_response_v4_to_v3( + x: v4::SqliteErrorResponse, +) -> Result { + Ok(v3::SqliteErrorResponse { message: x.message }) +} + +pub fn convert_sqlite_get_pages_response_v4_to_v3( + x: v4::SqliteGetPagesResponse, +) -> Result { + Ok(match x { + v4::SqliteGetPagesResponse::SqliteGetPagesOk(v) => { + v3::SqliteGetPagesResponse::SqliteGetPagesOk(convert_sqlite_get_pages_ok_v4_to_v3(v)?) + } + v4::SqliteGetPagesResponse::SqliteErrorResponse(v) => { + v3::SqliteGetPagesResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v3( + v, + )?) + } + }) +} + +pub fn convert_sqlite_commit_request_v4_to_v3( + x: v4::SqliteCommitRequest, +) -> Result { + Ok(v3::SqliteCommitRequest { + actor_id: x.actor_id, + dirty_pages: x + .dirty_pages + .into_iter() + .map(|v| convert_sqlite_dirty_page_v4_to_v3(v)) + .collect::>>()?, + db_size_pages: x.db_size_pages, + now_ms: x.now_ms, + expected_generation: x.expected_generation, + expected_head_txid: x.expected_head_txid, + }) +} + +pub fn convert_sqlite_commit_response_v4_to_v3( + x: v4::SqliteCommitResponse, +) -> Result { + Ok(match x { + v4::SqliteCommitResponse::SqliteCommitOk => v3::SqliteCommitResponse::SqliteCommitOk, + v4::SqliteCommitResponse::SqliteErrorResponse(v) => { + v3::SqliteCommitResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v3( + v, + )?) + } + }) +} + +pub fn convert_stop_code_v4_to_v3(x: v4::StopCode) -> Result { + Ok(match x { + v4::StopCode::Ok => v3::StopCode::Ok, + v4::StopCode::Error => v3::StopCode::Error, + }) +} + +pub fn convert_actor_name_v4_to_v3(x: v4::ActorName) -> Result { + Ok(v3::ActorName { + metadata: x.metadata, + }) +} + +pub fn convert_actor_config_v4_to_v3(x: v4::ActorConfig) -> Result { + Ok(v3::ActorConfig { + name: x.name, + key: x.key, + create_ts: x.create_ts, + input: x.input, + }) +} + +pub fn convert_actor_checkpoint_v4_to_v3(x: v4::ActorCheckpoint) -> Result { + Ok(v3::ActorCheckpoint { + actor_id: x.actor_id, + generation: x.generation, + index: x.index, + }) +} + +pub fn convert_actor_intent_v4_to_v3(x: v4::ActorIntent) -> Result { + Ok(match x { + v4::ActorIntent::ActorIntentSleep => v3::ActorIntent::ActorIntentSleep, + v4::ActorIntent::ActorIntentStop => v3::ActorIntent::ActorIntentStop, + }) +} + +pub fn convert_actor_state_stopped_v4_to_v3( + x: v4::ActorStateStopped, +) -> Result { + Ok(v3::ActorStateStopped { + code: convert_stop_code_v4_to_v3(x.code)?, + message: x.message, + }) +} + +pub fn convert_actor_state_v4_to_v3(x: v4::ActorState) -> Result { + Ok(match x { + v4::ActorState::ActorStateRunning => v3::ActorState::ActorStateRunning, + v4::ActorState::ActorStateStopped(v) => { + v3::ActorState::ActorStateStopped(convert_actor_state_stopped_v4_to_v3(v)?) + } + }) +} + +pub fn convert_event_actor_intent_v4_to_v3( + x: v4::EventActorIntent, +) -> Result { + Ok(v3::EventActorIntent { + intent: convert_actor_intent_v4_to_v3(x.intent)?, + }) +} + +pub fn convert_event_actor_state_update_v4_to_v3( + x: v4::EventActorStateUpdate, +) -> Result { + Ok(v3::EventActorStateUpdate { + state: convert_actor_state_v4_to_v3(x.state)?, + }) +} + +pub fn convert_event_actor_set_alarm_v4_to_v3( + x: v4::EventActorSetAlarm, +) -> Result { + Ok(v3::EventActorSetAlarm { + alarm_ts: x.alarm_ts, + }) +} + +pub fn convert_event_v4_to_v3(x: v4::Event) -> Result { + Ok(match x { + v4::Event::EventActorIntent(v) => { + v3::Event::EventActorIntent(convert_event_actor_intent_v4_to_v3(v)?) + } + v4::Event::EventActorStateUpdate(v) => { + v3::Event::EventActorStateUpdate(convert_event_actor_state_update_v4_to_v3(v)?) + } + v4::Event::EventActorSetAlarm(v) => { + v3::Event::EventActorSetAlarm(convert_event_actor_set_alarm_v4_to_v3(v)?) + } + }) +} + +pub fn convert_event_wrapper_v4_to_v3(x: v4::EventWrapper) -> Result { + Ok(v3::EventWrapper { + checkpoint: convert_actor_checkpoint_v4_to_v3(x.checkpoint)?, + inner: convert_event_v4_to_v3(x.inner)?, + }) +} + +pub fn convert_preloaded_kv_entry_v4_to_v3( + x: v4::PreloadedKvEntry, +) -> Result { + Ok(v3::PreloadedKvEntry { + key: x.key, + value: x.value, + metadata: convert_kv_metadata_v4_to_v3(x.metadata)?, + }) +} + +pub fn convert_preloaded_kv_v4_to_v3(x: v4::PreloadedKv) -> Result { + Ok(v3::PreloadedKv { + entries: x + .entries + .into_iter() + .map(|v| convert_preloaded_kv_entry_v4_to_v3(v)) + .collect::>>()?, + requested_get_keys: x.requested_get_keys, + requested_prefixes: x.requested_prefixes, + }) +} + +pub fn convert_hibernating_request_v4_to_v3( + x: v4::HibernatingRequest, +) -> Result { + Ok(v3::HibernatingRequest { + gateway_id: x.gateway_id, + request_id: x.request_id, + }) +} + +pub fn convert_command_start_actor_v4_to_v3( + x: v4::CommandStartActor, +) -> Result { + Ok(v3::CommandStartActor { + config: convert_actor_config_v4_to_v3(x.config)?, + hibernating_requests: x + .hibernating_requests + .into_iter() + .map(|v| convert_hibernating_request_v4_to_v3(v)) + .collect::>>()?, + preloaded_kv: x + .preloaded_kv + .map(|v| convert_preloaded_kv_v4_to_v3(v)) + .transpose()?, + }) +} + +pub fn convert_stop_actor_reason_v4_to_v3(x: v4::StopActorReason) -> Result { + Ok(match x { + v4::StopActorReason::SleepIntent => v3::StopActorReason::SleepIntent, + v4::StopActorReason::StopIntent => v3::StopActorReason::StopIntent, + v4::StopActorReason::Destroy => v3::StopActorReason::Destroy, + v4::StopActorReason::GoingAway => v3::StopActorReason::GoingAway, + v4::StopActorReason::Lost => v3::StopActorReason::Lost, + }) +} + +pub fn convert_command_stop_actor_v4_to_v3( + x: v4::CommandStopActor, +) -> Result { + Ok(v3::CommandStopActor { + reason: convert_stop_actor_reason_v4_to_v3(x.reason)?, + }) +} + +pub fn convert_command_v4_to_v3(x: v4::Command) -> Result { + Ok(match x { + v4::Command::CommandStartActor(v) => { + v3::Command::CommandStartActor(convert_command_start_actor_v4_to_v3(v)?) + } + v4::Command::CommandStopActor(v) => { + v3::Command::CommandStopActor(convert_command_stop_actor_v4_to_v3(v)?) + } + }) +} + +pub fn convert_command_wrapper_v4_to_v3(x: v4::CommandWrapper) -> Result { + Ok(v3::CommandWrapper { + checkpoint: convert_actor_checkpoint_v4_to_v3(x.checkpoint)?, + inner: convert_command_v4_to_v3(x.inner)?, + }) +} + +pub fn convert_actor_command_key_data_v4_to_v3( + x: v4::ActorCommandKeyData, +) -> Result { + Ok(match x { + v4::ActorCommandKeyData::CommandStartActor(v) => { + v3::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v4_to_v3(v)?) + } + v4::ActorCommandKeyData::CommandStopActor(v) => { + v3::ActorCommandKeyData::CommandStopActor(convert_command_stop_actor_v4_to_v3(v)?) + } + }) +} + +pub fn convert_message_id_v4_to_v3(x: v4::MessageId) -> Result { + Ok(v3::MessageId { + gateway_id: x.gateway_id, + request_id: x.request_id, + message_index: x.message_index, + }) +} + +pub fn convert_to_envoy_request_start_v4_to_v3( + x: v4::ToEnvoyRequestStart, +) -> Result { + Ok(v3::ToEnvoyRequestStart { + actor_id: x.actor_id, + method: x.method, + path: x.path, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_envoy_request_chunk_v4_to_v3( + x: v4::ToEnvoyRequestChunk, +) -> Result { + Ok(v3::ToEnvoyRequestChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_rivet_response_start_v4_to_v3( + x: v4::ToRivetResponseStart, +) -> Result { + Ok(v3::ToRivetResponseStart { + status: x.status, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_rivet_response_chunk_v4_to_v3( + x: v4::ToRivetResponseChunk, +) -> Result { + Ok(v3::ToRivetResponseChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_envoy_web_socket_open_v4_to_v3( + x: v4::ToEnvoyWebSocketOpen, +) -> Result { + Ok(v3::ToEnvoyWebSocketOpen { + actor_id: x.actor_id, + path: x.path, + headers: x.headers, + }) +} + +pub fn convert_to_envoy_web_socket_message_v4_to_v3( + x: v4::ToEnvoyWebSocketMessage, +) -> Result { + Ok(v3::ToEnvoyWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_envoy_web_socket_close_v4_to_v3( + x: v4::ToEnvoyWebSocketClose, +) -> Result { + Ok(v3::ToEnvoyWebSocketClose { + code: x.code, + reason: x.reason, + }) +} + +pub fn convert_to_rivet_web_socket_open_v4_to_v3( + x: v4::ToRivetWebSocketOpen, +) -> Result { + Ok(v3::ToRivetWebSocketOpen { + can_hibernate: x.can_hibernate, + }) +} + +pub fn convert_to_rivet_web_socket_message_v4_to_v3( + x: v4::ToRivetWebSocketMessage, +) -> Result { + Ok(v3::ToRivetWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_rivet_web_socket_message_ack_v4_to_v3( + x: v4::ToRivetWebSocketMessageAck, +) -> Result { + Ok(v3::ToRivetWebSocketMessageAck { index: x.index }) +} + +pub fn convert_to_rivet_web_socket_close_v4_to_v3( + x: v4::ToRivetWebSocketClose, +) -> Result { + Ok(v3::ToRivetWebSocketClose { + code: x.code, + reason: x.reason, + hibernate: x.hibernate, + }) +} + +pub fn convert_to_rivet_tunnel_message_kind_v4_to_v3( + x: v4::ToRivetTunnelMessageKind, +) -> Result { + Ok(match x { + v4::ToRivetTunnelMessageKind::ToRivetResponseStart(v) => { + v3::ToRivetTunnelMessageKind::ToRivetResponseStart( + convert_to_rivet_response_start_v4_to_v3(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetResponseChunk(v) => { + v3::ToRivetTunnelMessageKind::ToRivetResponseChunk( + convert_to_rivet_response_chunk_v4_to_v3(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetResponseAbort => { + v3::ToRivetTunnelMessageKind::ToRivetResponseAbort + } + v4::ToRivetTunnelMessageKind::ToRivetWebSocketOpen(v) => { + v3::ToRivetTunnelMessageKind::ToRivetWebSocketOpen( + convert_to_rivet_web_socket_open_v4_to_v3(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetWebSocketMessage(v) => { + v3::ToRivetTunnelMessageKind::ToRivetWebSocketMessage( + convert_to_rivet_web_socket_message_v4_to_v3(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck(v) => { + v3::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck( + convert_to_rivet_web_socket_message_ack_v4_to_v3(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetWebSocketClose(v) => { + v3::ToRivetTunnelMessageKind::ToRivetWebSocketClose( + convert_to_rivet_web_socket_close_v4_to_v3(v)?, + ) + } + }) +} + +pub fn convert_to_rivet_tunnel_message_v4_to_v3( + x: v4::ToRivetTunnelMessage, +) -> Result { + Ok(v3::ToRivetTunnelMessage { + message_id: convert_message_id_v4_to_v3(x.message_id)?, + message_kind: convert_to_rivet_tunnel_message_kind_v4_to_v3(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_tunnel_message_kind_v4_to_v3( + x: v4::ToEnvoyTunnelMessageKind, +) -> Result { + Ok(match x { + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart( + convert_to_envoy_request_start_v4_to_v3(v)?, + ) + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk( + convert_to_envoy_request_chunk_v4_to_v3(v)?, + ) + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen( + convert_to_envoy_web_socket_open_v4_to_v3(v)?, + ) + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage( + convert_to_envoy_web_socket_message_v4_to_v3(v)?, + ) + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose(v) => { + v3::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose( + convert_to_envoy_web_socket_close_v4_to_v3(v)?, + ) + } + }) +} + +pub fn convert_to_envoy_tunnel_message_v4_to_v3( + x: v4::ToEnvoyTunnelMessage, +) -> Result { + Ok(v3::ToEnvoyTunnelMessage { + message_id: convert_message_id_v4_to_v3(x.message_id)?, + message_kind: convert_to_envoy_tunnel_message_kind_v4_to_v3(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_ping_v4_to_v3(x: v4::ToEnvoyPing) -> Result { + Ok(v3::ToEnvoyPing { ts: x.ts }) +} + +pub fn convert_to_rivet_metadata_v4_to_v3(x: v4::ToRivetMetadata) -> Result { + Ok(v3::ToRivetMetadata { + prepopulate_actor_names: x + .prepopulate_actor_names + .map(|v| { + v.into_iter() + .map(|(k, v)| -> Result<_> { Ok((k, convert_actor_name_v4_to_v3(v)?)) }) + .collect::>() + }) + .transpose()?, + metadata: x.metadata, + }) +} + +pub fn convert_to_rivet_events_v4_to_v3(x: v4::ToRivetEvents) -> Result { + Ok(x.into_iter() + .map(|v| convert_event_wrapper_v4_to_v3(v)) + .collect::>>()?) +} + +pub fn convert_to_rivet_ack_commands_v4_to_v3( + x: v4::ToRivetAckCommands, +) -> Result { + Ok(v3::ToRivetAckCommands { + last_command_checkpoints: x + .last_command_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v4_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_rivet_pong_v4_to_v3(x: v4::ToRivetPong) -> Result { + Ok(v3::ToRivetPong { ts: x.ts }) +} + +pub fn convert_to_rivet_kv_request_v4_to_v3( + x: v4::ToRivetKvRequest, +) -> Result { + Ok(v3::ToRivetKvRequest { + actor_id: x.actor_id, + request_id: x.request_id, + data: convert_kv_request_data_v4_to_v3(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_get_pages_request_v4_to_v3( + x: v4::ToRivetSqliteGetPagesRequest, +) -> Result { + Ok(v3::ToRivetSqliteGetPagesRequest { + request_id: x.request_id, + data: convert_sqlite_get_pages_request_v4_to_v3(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_commit_request_v4_to_v3( + x: v4::ToRivetSqliteCommitRequest, +) -> Result { + Ok(v3::ToRivetSqliteCommitRequest { + request_id: x.request_id, + data: convert_sqlite_commit_request_v4_to_v3(x.data)?, + }) +} + +pub fn convert_to_rivet_v4_to_v3(x: v4::ToRivet) -> Result { + Ok(match x { + v4::ToRivet::ToRivetMetadata(v) => { + v3::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v4_to_v3(v)?) + } + v4::ToRivet::ToRivetEvents(v) => { + v3::ToRivet::ToRivetEvents(convert_to_rivet_events_v4_to_v3(v)?) + } + v4::ToRivet::ToRivetAckCommands(v) => { + v3::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v4_to_v3(v)?) + } + v4::ToRivet::ToRivetStopping => v3::ToRivet::ToRivetStopping, + v4::ToRivet::ToRivetPong(v) => v3::ToRivet::ToRivetPong(convert_to_rivet_pong_v4_to_v3(v)?), + v4::ToRivet::ToRivetKvRequest(v) => { + v3::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v4_to_v3(v)?) + } + v4::ToRivet::ToRivetTunnelMessage(v) => { + v3::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v4_to_v3(v)?) + } + v4::ToRivet::ToRivetSqliteGetPagesRequest(v) => v3::ToRivet::ToRivetSqliteGetPagesRequest( + convert_to_rivet_sqlite_get_pages_request_v4_to_v3(v)?, + ), + v4::ToRivet::ToRivetSqliteCommitRequest(v) => v3::ToRivet::ToRivetSqliteCommitRequest( + convert_to_rivet_sqlite_commit_request_v4_to_v3(v)?, + ), + v4::ToRivet::ToRivetSqliteExecRequest(_) | v4::ToRivet::ToRivetSqliteExecuteRequest(_) => { + return Err(incompatible( + ProtocolCompatibilityFeature::RemoteSqliteExecution, + ProtocolCompatibilityDirection::ToRivet, + 4, + 3, + )); + } + }) +} + +pub fn convert_protocol_metadata_v4_to_v3(x: v4::ProtocolMetadata) -> Result { + Ok(v3::ProtocolMetadata { + envoy_lost_threshold: x.envoy_lost_threshold, + actor_stop_threshold: x.actor_stop_threshold, + max_response_payload_size: x.max_response_payload_size, + }) +} + +pub fn convert_to_envoy_init_v4_to_v3(x: v4::ToEnvoyInit) -> Result { + Ok(v3::ToEnvoyInit { + metadata: convert_protocol_metadata_v4_to_v3(x.metadata)?, + }) +} + +pub fn convert_to_envoy_commands_v4_to_v3(x: v4::ToEnvoyCommands) -> Result { + Ok(x.into_iter() + .map(|v| convert_command_wrapper_v4_to_v3(v)) + .collect::>>()?) +} + +pub fn convert_to_envoy_ack_events_v4_to_v3( + x: v4::ToEnvoyAckEvents, +) -> Result { + Ok(v3::ToEnvoyAckEvents { + last_event_checkpoints: x + .last_event_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v4_to_v3(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_envoy_kv_response_v4_to_v3( + x: v4::ToEnvoyKvResponse, +) -> Result { + Ok(v3::ToEnvoyKvResponse { + request_id: x.request_id, + data: convert_kv_response_data_v4_to_v3(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_get_pages_response_v4_to_v3( + x: v4::ToEnvoySqliteGetPagesResponse, +) -> Result { + Ok(v3::ToEnvoySqliteGetPagesResponse { + request_id: x.request_id, + data: convert_sqlite_get_pages_response_v4_to_v3(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_commit_response_v4_to_v3( + x: v4::ToEnvoySqliteCommitResponse, +) -> Result { + Ok(v3::ToEnvoySqliteCommitResponse { + request_id: x.request_id, + data: convert_sqlite_commit_response_v4_to_v3(x.data)?, + }) +} + +pub fn convert_to_envoy_v4_to_v3(x: v4::ToEnvoy) -> Result { + Ok(match x { + v4::ToEnvoy::ToEnvoyInit(v) => v3::ToEnvoy::ToEnvoyInit(convert_to_envoy_init_v4_to_v3(v)?), + v4::ToEnvoy::ToEnvoyCommands(v) => { + v3::ToEnvoy::ToEnvoyCommands(convert_to_envoy_commands_v4_to_v3(v)?) + } + v4::ToEnvoy::ToEnvoyAckEvents(v) => { + v3::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v4_to_v3(v)?) + } + v4::ToEnvoy::ToEnvoyKvResponse(v) => { + v3::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v4_to_v3(v)?) + } + v4::ToEnvoy::ToEnvoyTunnelMessage(v) => { + v3::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v4_to_v3(v)?) + } + v4::ToEnvoy::ToEnvoyPing(v) => v3::ToEnvoy::ToEnvoyPing(convert_to_envoy_ping_v4_to_v3(v)?), + v4::ToEnvoy::ToEnvoySqliteGetPagesResponse(v) => { + v3::ToEnvoy::ToEnvoySqliteGetPagesResponse( + convert_to_envoy_sqlite_get_pages_response_v4_to_v3(v)?, + ) + } + v4::ToEnvoy::ToEnvoySqliteCommitResponse(v) => v3::ToEnvoy::ToEnvoySqliteCommitResponse( + convert_to_envoy_sqlite_commit_response_v4_to_v3(v)?, + ), + v4::ToEnvoy::ToEnvoySqliteExecResponse(_) + | v4::ToEnvoy::ToEnvoySqliteExecuteResponse(_) => { + return Err(incompatible( + ProtocolCompatibilityFeature::RemoteSqliteExecution, + ProtocolCompatibilityDirection::ToEnvoy, + 4, + 3, + )); + } + }) +} + +pub fn convert_to_envoy_conn_ping_v4_to_v3(x: v4::ToEnvoyConnPing) -> Result { + Ok(v3::ToEnvoyConnPing { + gateway_id: x.gateway_id, + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_envoy_conn_v4_to_v3(x: v4::ToEnvoyConn) -> Result { + Ok(match x { + v4::ToEnvoyConn::ToEnvoyConnPing(v) => { + v3::ToEnvoyConn::ToEnvoyConnPing(convert_to_envoy_conn_ping_v4_to_v3(v)?) + } + v4::ToEnvoyConn::ToEnvoyConnClose => v3::ToEnvoyConn::ToEnvoyConnClose, + v4::ToEnvoyConn::ToEnvoyCommands(v) => { + v3::ToEnvoyConn::ToEnvoyCommands(convert_to_envoy_commands_v4_to_v3(v)?) + } + v4::ToEnvoyConn::ToEnvoyAckEvents(v) => { + v3::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v4_to_v3(v)?) + } + v4::ToEnvoyConn::ToEnvoyTunnelMessage(v) => { + v3::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v4_to_v3(v)?) + } + }) +} + +pub fn convert_to_gateway_pong_v4_to_v3(x: v4::ToGatewayPong) -> Result { + Ok(v3::ToGatewayPong { + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_gateway_v4_to_v3(x: v4::ToGateway) -> Result { + Ok(match x { + v4::ToGateway::ToGatewayPong(v) => { + v3::ToGateway::ToGatewayPong(convert_to_gateway_pong_v4_to_v3(v)?) + } + v4::ToGateway::ToRivetTunnelMessage(v) => { + v3::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v4_to_v3(v)?) + } + }) +} + +pub fn convert_to_outbound_actor_start_v4_to_v3( + x: v4::ToOutboundActorStart, +) -> Result { + Ok(v3::ToOutboundActorStart { + namespace_id: x.namespace_id, + pool_name: x.pool_name, + checkpoint: convert_actor_checkpoint_v4_to_v3(x.checkpoint)?, + actor_config: convert_actor_config_v4_to_v3(x.actor_config)?, + }) +} + +pub fn convert_to_outbound_v4_to_v3(x: v4::ToOutbound) -> Result { + Ok(match x { + v4::ToOutbound::ToOutboundActorStart(v) => { + v3::ToOutbound::ToOutboundActorStart(convert_to_outbound_actor_start_v4_to_v3(v)?) + } + }) +} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned/v4_to_v5.rs b/engine/sdks/rust/envoy-protocol/src/versioned/v4_to_v5.rs new file mode 100644 index 0000000000..0e52df71ac --- /dev/null +++ b/engine/sdks/rust/envoy-protocol/src/versioned/v4_to_v5.rs @@ -0,0 +1,1100 @@ +// @generated initial scaffold by scripts/vbare-gen-converters +// from: v4.bare, to: v5.bare +// Replace each todo!() with the migration semantics, then drop the @generated marker. + +#![allow(dead_code, unused_variables)] + +use anyhow::Result; + +use crate::generated::{v4, v5}; + +pub fn convert_kv_metadata_v4_to_v5(x: v4::KvMetadata) -> Result { + Ok(v5::KvMetadata { + version: x.version, + update_ts: x.update_ts, + }) +} + +pub fn convert_kv_list_range_query_v4_to_v5( + x: v4::KvListRangeQuery, +) -> Result { + Ok(v5::KvListRangeQuery { + start: x.start, + end: x.end, + exclusive: x.exclusive, + }) +} + +pub fn convert_kv_list_prefix_query_v4_to_v5( + x: v4::KvListPrefixQuery, +) -> Result { + Ok(v5::KvListPrefixQuery { key: x.key }) +} + +pub fn convert_kv_list_query_v4_to_v5(x: v4::KvListQuery) -> Result { + Ok(match x { + v4::KvListQuery::KvListAllQuery => v5::KvListQuery::KvListAllQuery, + v4::KvListQuery::KvListRangeQuery(v) => { + v5::KvListQuery::KvListRangeQuery(convert_kv_list_range_query_v4_to_v5(v)?) + } + v4::KvListQuery::KvListPrefixQuery(v) => { + v5::KvListQuery::KvListPrefixQuery(convert_kv_list_prefix_query_v4_to_v5(v)?) + } + }) +} + +pub fn convert_kv_get_request_v4_to_v5(x: v4::KvGetRequest) -> Result { + Ok(v5::KvGetRequest { keys: x.keys }) +} + +pub fn convert_kv_list_request_v4_to_v5(x: v4::KvListRequest) -> Result { + Ok(v5::KvListRequest { + query: convert_kv_list_query_v4_to_v5(x.query)?, + reverse: x.reverse, + limit: x.limit, + }) +} + +pub fn convert_kv_put_request_v4_to_v5(x: v4::KvPutRequest) -> Result { + Ok(v5::KvPutRequest { + keys: x.keys, + values: x.values, + }) +} + +pub fn convert_kv_delete_request_v4_to_v5(x: v4::KvDeleteRequest) -> Result { + Ok(v5::KvDeleteRequest { keys: x.keys }) +} + +pub fn convert_kv_delete_range_request_v4_to_v5( + x: v4::KvDeleteRangeRequest, +) -> Result { + Ok(v5::KvDeleteRangeRequest { + start: x.start, + end: x.end, + }) +} + +pub fn convert_kv_error_response_v4_to_v5(x: v4::KvErrorResponse) -> Result { + Ok(v5::KvErrorResponse { message: x.message }) +} + +pub fn convert_kv_get_response_v4_to_v5(x: v4::KvGetResponse) -> Result { + Ok(v5::KvGetResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v4_to_v5(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_list_response_v4_to_v5(x: v4::KvListResponse) -> Result { + Ok(v5::KvListResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v4_to_v5(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_request_data_v4_to_v5(x: v4::KvRequestData) -> Result { + Ok(match x { + v4::KvRequestData::KvGetRequest(v) => { + v5::KvRequestData::KvGetRequest(convert_kv_get_request_v4_to_v5(v)?) + } + v4::KvRequestData::KvListRequest(v) => { + v5::KvRequestData::KvListRequest(convert_kv_list_request_v4_to_v5(v)?) + } + v4::KvRequestData::KvPutRequest(v) => { + v5::KvRequestData::KvPutRequest(convert_kv_put_request_v4_to_v5(v)?) + } + v4::KvRequestData::KvDeleteRequest(v) => { + v5::KvRequestData::KvDeleteRequest(convert_kv_delete_request_v4_to_v5(v)?) + } + v4::KvRequestData::KvDeleteRangeRequest(v) => { + v5::KvRequestData::KvDeleteRangeRequest(convert_kv_delete_range_request_v4_to_v5(v)?) + } + v4::KvRequestData::KvDropRequest => v5::KvRequestData::KvDropRequest, + }) +} + +pub fn convert_kv_response_data_v4_to_v5(x: v4::KvResponseData) -> Result { + Ok(match x { + v4::KvResponseData::KvErrorResponse(v) => { + v5::KvResponseData::KvErrorResponse(convert_kv_error_response_v4_to_v5(v)?) + } + v4::KvResponseData::KvGetResponse(v) => { + v5::KvResponseData::KvGetResponse(convert_kv_get_response_v4_to_v5(v)?) + } + v4::KvResponseData::KvListResponse(v) => { + v5::KvResponseData::KvListResponse(convert_kv_list_response_v4_to_v5(v)?) + } + v4::KvResponseData::KvPutResponse => v5::KvResponseData::KvPutResponse, + v4::KvResponseData::KvDeleteResponse => v5::KvResponseData::KvDeleteResponse, + v4::KvResponseData::KvDropResponse => v5::KvResponseData::KvDropResponse, + }) +} + +pub fn convert_sqlite_dirty_page_v4_to_v5(x: v4::SqliteDirtyPage) -> Result { + Ok(v5::SqliteDirtyPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_fetched_page_v4_to_v5( + x: v4::SqliteFetchedPage, +) -> Result { + Ok(v5::SqliteFetchedPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_get_pages_request_v4_to_v5( + x: v4::SqliteGetPagesRequest, +) -> Result { + Ok(v5::SqliteGetPagesRequest { + actor_id: x.actor_id, + pgnos: x.pgnos, + expected_generation: x.expected_generation, + expected_head_txid: x.expected_head_txid, + }) +} + +pub fn convert_sqlite_get_pages_ok_v4_to_v5( + x: v4::SqliteGetPagesOk, +) -> Result { + Ok(v5::SqliteGetPagesOk { + pages: x + .pages + .into_iter() + .map(|v| convert_sqlite_fetched_page_v4_to_v5(v)) + .collect::>>()?, + // v4 had no head_txid in the response; v5 callers treat None as "unknown". + head_txid: None, + }) +} + +pub fn convert_sqlite_error_response_v4_to_v5( + x: v4::SqliteErrorResponse, +) -> Result { + Ok(v5::SqliteErrorResponse { + // v4 errors were untyped strings; lift to the canonical RivetError shape. + group: "core".to_string(), + code: "internal_error".to_string(), + message: x.message, + }) +} + +pub fn convert_sqlite_get_pages_response_v4_to_v5( + x: v4::SqliteGetPagesResponse, +) -> Result { + Ok(match x { + v4::SqliteGetPagesResponse::SqliteGetPagesOk(v) => { + v5::SqliteGetPagesResponse::SqliteGetPagesOk(convert_sqlite_get_pages_ok_v4_to_v5(v)?) + } + v4::SqliteGetPagesResponse::SqliteErrorResponse(v) => { + v5::SqliteGetPagesResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v5( + v, + )?) + } + }) +} + +pub fn convert_sqlite_commit_request_v4_to_v5( + x: v4::SqliteCommitRequest, +) -> Result { + Ok(v5::SqliteCommitRequest { + actor_id: x.actor_id, + dirty_pages: x + .dirty_pages + .into_iter() + .map(|v| convert_sqlite_dirty_page_v4_to_v5(v)) + .collect::>>()?, + db_size_pages: x.db_size_pages, + now_ms: x.now_ms, + expected_generation: x.expected_generation, + expected_head_txid: x.expected_head_txid, + }) +} + +pub fn convert_sqlite_commit_response_v4_to_v5( + x: v4::SqliteCommitResponse, +) -> Result { + Ok(match x { + v4::SqliteCommitResponse::SqliteCommitOk => { + // v4's SqliteCommitOk was a void variant; v5 carries an optional head_txid. + v5::SqliteCommitResponse::SqliteCommitOk(v5::SqliteCommitOk { head_txid: None }) + } + v4::SqliteCommitResponse::SqliteErrorResponse(v) => { + v5::SqliteCommitResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v5( + v, + )?) + } + }) +} + +pub fn convert_sqlite_value_integer_v4_to_v5( + x: v4::SqliteValueInteger, +) -> Result { + Ok(v5::SqliteValueInteger { value: x.value }) +} + +pub fn convert_sqlite_value_float_v4_to_v5( + x: v4::SqliteValueFloat, +) -> Result { + Ok(v5::SqliteValueFloat { value: x.value }) +} + +pub fn convert_sqlite_value_text_v4_to_v5(x: v4::SqliteValueText) -> Result { + Ok(v5::SqliteValueText { value: x.value }) +} + +pub fn convert_sqlite_value_blob_v4_to_v5(x: v4::SqliteValueBlob) -> Result { + Ok(v5::SqliteValueBlob { value: x.value }) +} + +pub fn convert_sqlite_bind_param_v4_to_v5(x: v4::SqliteBindParam) -> Result { + Ok(match x { + v4::SqliteBindParam::SqliteValueNull => v5::SqliteBindParam::SqliteValueNull, + v4::SqliteBindParam::SqliteValueInteger(v) => { + v5::SqliteBindParam::SqliteValueInteger(convert_sqlite_value_integer_v4_to_v5(v)?) + } + v4::SqliteBindParam::SqliteValueFloat(v) => { + v5::SqliteBindParam::SqliteValueFloat(convert_sqlite_value_float_v4_to_v5(v)?) + } + v4::SqliteBindParam::SqliteValueText(v) => { + v5::SqliteBindParam::SqliteValueText(convert_sqlite_value_text_v4_to_v5(v)?) + } + v4::SqliteBindParam::SqliteValueBlob(v) => { + v5::SqliteBindParam::SqliteValueBlob(convert_sqlite_value_blob_v4_to_v5(v)?) + } + }) +} + +pub fn convert_sqlite_column_value_v4_to_v5( + x: v4::SqliteColumnValue, +) -> Result { + Ok(match x { + v4::SqliteColumnValue::SqliteValueNull => v5::SqliteColumnValue::SqliteValueNull, + v4::SqliteColumnValue::SqliteValueInteger(v) => { + v5::SqliteColumnValue::SqliteValueInteger(convert_sqlite_value_integer_v4_to_v5(v)?) + } + v4::SqliteColumnValue::SqliteValueFloat(v) => { + v5::SqliteColumnValue::SqliteValueFloat(convert_sqlite_value_float_v4_to_v5(v)?) + } + v4::SqliteColumnValue::SqliteValueText(v) => { + v5::SqliteColumnValue::SqliteValueText(convert_sqlite_value_text_v4_to_v5(v)?) + } + v4::SqliteColumnValue::SqliteValueBlob(v) => { + v5::SqliteColumnValue::SqliteValueBlob(convert_sqlite_value_blob_v4_to_v5(v)?) + } + }) +} + +pub fn convert_sqlite_query_result_v4_to_v5( + x: v4::SqliteQueryResult, +) -> Result { + Ok(v5::SqliteQueryResult { + columns: x.columns, + rows: x + .rows + .into_iter() + .map(|v| { + v.into_iter() + .map(|v| convert_sqlite_column_value_v4_to_v5(v)) + .collect::>>() + }) + .collect::>>()?, + }) +} + +pub fn convert_sqlite_execute_result_v4_to_v5( + x: v4::SqliteExecuteResult, +) -> Result { + Ok(v5::SqliteExecuteResult { + columns: x.columns, + rows: x + .rows + .into_iter() + .map(|v| { + v.into_iter() + .map(|v| convert_sqlite_column_value_v4_to_v5(v)) + .collect::>>() + }) + .collect::>>()?, + changes: x.changes, + last_insert_row_id: x.last_insert_row_id, + }) +} + +pub fn convert_sqlite_exec_request_v4_to_v5( + x: v4::SqliteExecRequest, +) -> Result { + Ok(v5::SqliteExecRequest { + namespace_id: x.namespace_id, + actor_id: x.actor_id, + generation: x.generation, + sql: x.sql, + }) +} + +pub fn convert_sqlite_execute_request_v4_to_v5( + x: v4::SqliteExecuteRequest, +) -> Result { + Ok(v5::SqliteExecuteRequest { + namespace_id: x.namespace_id, + actor_id: x.actor_id, + generation: x.generation, + sql: x.sql, + params: x + .params + .map(|v| { + v.into_iter() + .map(|v| convert_sqlite_bind_param_v4_to_v5(v)) + .collect::>>() + }) + .transpose()?, + }) +} + +pub fn convert_sqlite_exec_ok_v4_to_v5(x: v4::SqliteExecOk) -> Result { + Ok(v5::SqliteExecOk { + result: convert_sqlite_query_result_v4_to_v5(x.result)?, + }) +} + +pub fn convert_sqlite_execute_ok_v4_to_v5(x: v4::SqliteExecuteOk) -> Result { + Ok(v5::SqliteExecuteOk { + result: convert_sqlite_execute_result_v4_to_v5(x.result)?, + }) +} + +pub fn convert_sqlite_exec_response_v4_to_v5( + x: v4::SqliteExecResponse, +) -> Result { + Ok(match x { + v4::SqliteExecResponse::SqliteExecOk(v) => { + v5::SqliteExecResponse::SqliteExecOk(convert_sqlite_exec_ok_v4_to_v5(v)?) + } + v4::SqliteExecResponse::SqliteErrorResponse(v) => { + v5::SqliteExecResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v5(v)?) + } + }) +} + +pub fn convert_sqlite_execute_response_v4_to_v5( + x: v4::SqliteExecuteResponse, +) -> Result { + Ok(match x { + v4::SqliteExecuteResponse::SqliteExecuteOk(v) => { + v5::SqliteExecuteResponse::SqliteExecuteOk(convert_sqlite_execute_ok_v4_to_v5(v)?) + } + v4::SqliteExecuteResponse::SqliteErrorResponse(v) => { + v5::SqliteExecuteResponse::SqliteErrorResponse(convert_sqlite_error_response_v4_to_v5( + v, + )?) + } + }) +} + +pub fn convert_stop_code_v4_to_v5(x: v4::StopCode) -> Result { + Ok(match x { + v4::StopCode::Ok => v5::StopCode::Ok, + v4::StopCode::Error => v5::StopCode::Error, + }) +} + +pub fn convert_actor_name_v4_to_v5(x: v4::ActorName) -> Result { + Ok(v5::ActorName { + metadata: x.metadata, + }) +} + +pub fn convert_actor_config_v4_to_v5(x: v4::ActorConfig) -> Result { + Ok(v5::ActorConfig { + name: x.name, + key: x.key, + create_ts: x.create_ts, + input: x.input, + }) +} + +pub fn convert_actor_checkpoint_v4_to_v5(x: v4::ActorCheckpoint) -> Result { + Ok(v5::ActorCheckpoint { + actor_id: x.actor_id, + generation: x.generation, + index: x.index, + }) +} + +pub fn convert_actor_intent_v4_to_v5(x: v4::ActorIntent) -> Result { + Ok(match x { + v4::ActorIntent::ActorIntentSleep => v5::ActorIntent::ActorIntentSleep, + v4::ActorIntent::ActorIntentStop => v5::ActorIntent::ActorIntentStop, + }) +} + +pub fn convert_actor_state_stopped_v4_to_v5( + x: v4::ActorStateStopped, +) -> Result { + Ok(v5::ActorStateStopped { + code: convert_stop_code_v4_to_v5(x.code)?, + message: x.message, + }) +} + +pub fn convert_actor_state_v4_to_v5(x: v4::ActorState) -> Result { + Ok(match x { + v4::ActorState::ActorStateRunning => v5::ActorState::ActorStateRunning, + v4::ActorState::ActorStateStopped(v) => { + v5::ActorState::ActorStateStopped(convert_actor_state_stopped_v4_to_v5(v)?) + } + }) +} + +pub fn convert_event_actor_intent_v4_to_v5( + x: v4::EventActorIntent, +) -> Result { + Ok(v5::EventActorIntent { + intent: convert_actor_intent_v4_to_v5(x.intent)?, + }) +} + +pub fn convert_event_actor_state_update_v4_to_v5( + x: v4::EventActorStateUpdate, +) -> Result { + Ok(v5::EventActorStateUpdate { + state: convert_actor_state_v4_to_v5(x.state)?, + }) +} + +pub fn convert_event_actor_set_alarm_v4_to_v5( + x: v4::EventActorSetAlarm, +) -> Result { + Ok(v5::EventActorSetAlarm { + alarm_ts: x.alarm_ts, + }) +} + +pub fn convert_event_v4_to_v5(x: v4::Event) -> Result { + Ok(match x { + v4::Event::EventActorIntent(v) => { + v5::Event::EventActorIntent(convert_event_actor_intent_v4_to_v5(v)?) + } + v4::Event::EventActorStateUpdate(v) => { + v5::Event::EventActorStateUpdate(convert_event_actor_state_update_v4_to_v5(v)?) + } + v4::Event::EventActorSetAlarm(v) => { + v5::Event::EventActorSetAlarm(convert_event_actor_set_alarm_v4_to_v5(v)?) + } + }) +} + +pub fn convert_event_wrapper_v4_to_v5(x: v4::EventWrapper) -> Result { + Ok(v5::EventWrapper { + checkpoint: convert_actor_checkpoint_v4_to_v5(x.checkpoint)?, + inner: convert_event_v4_to_v5(x.inner)?, + }) +} + +pub fn convert_preloaded_kv_entry_v4_to_v5( + x: v4::PreloadedKvEntry, +) -> Result { + Ok(v5::PreloadedKvEntry { + key: x.key, + value: x.value, + metadata: convert_kv_metadata_v4_to_v5(x.metadata)?, + }) +} + +pub fn convert_preloaded_kv_v4_to_v5(x: v4::PreloadedKv) -> Result { + Ok(v5::PreloadedKv { + entries: x + .entries + .into_iter() + .map(|v| convert_preloaded_kv_entry_v4_to_v5(v)) + .collect::>>()?, + requested_get_keys: x.requested_get_keys, + requested_prefixes: x.requested_prefixes, + }) +} + +pub fn convert_hibernating_request_v4_to_v5( + x: v4::HibernatingRequest, +) -> Result { + Ok(v5::HibernatingRequest { + gateway_id: x.gateway_id, + request_id: x.request_id, + }) +} + +pub fn convert_command_start_actor_v4_to_v5( + x: v4::CommandStartActor, +) -> Result { + Ok(v5::CommandStartActor { + config: convert_actor_config_v4_to_v5(x.config)?, + hibernating_requests: x + .hibernating_requests + .into_iter() + .map(|v| convert_hibernating_request_v4_to_v5(v)) + .collect::>>()?, + preloaded_kv: x + .preloaded_kv + .map(|v| convert_preloaded_kv_v4_to_v5(v)) + .transpose()?, + }) +} + +pub fn convert_stop_actor_reason_v4_to_v5(x: v4::StopActorReason) -> Result { + Ok(match x { + v4::StopActorReason::SleepIntent => v5::StopActorReason::SleepIntent, + v4::StopActorReason::StopIntent => v5::StopActorReason::StopIntent, + v4::StopActorReason::Destroy => v5::StopActorReason::Destroy, + v4::StopActorReason::GoingAway => v5::StopActorReason::GoingAway, + v4::StopActorReason::Lost => v5::StopActorReason::Lost, + }) +} + +pub fn convert_command_stop_actor_v4_to_v5( + x: v4::CommandStopActor, +) -> Result { + Ok(v5::CommandStopActor { + reason: convert_stop_actor_reason_v4_to_v5(x.reason)?, + }) +} + +pub fn convert_command_v4_to_v5(x: v4::Command) -> Result { + Ok(match x { + v4::Command::CommandStartActor(v) => { + v5::Command::CommandStartActor(convert_command_start_actor_v4_to_v5(v)?) + } + v4::Command::CommandStopActor(v) => { + v5::Command::CommandStopActor(convert_command_stop_actor_v4_to_v5(v)?) + } + }) +} + +pub fn convert_command_wrapper_v4_to_v5(x: v4::CommandWrapper) -> Result { + Ok(v5::CommandWrapper { + checkpoint: convert_actor_checkpoint_v4_to_v5(x.checkpoint)?, + inner: convert_command_v4_to_v5(x.inner)?, + }) +} + +pub fn convert_actor_command_key_data_v4_to_v5( + x: v4::ActorCommandKeyData, +) -> Result { + Ok(match x { + v4::ActorCommandKeyData::CommandStartActor(v) => { + v5::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v4_to_v5(v)?) + } + v4::ActorCommandKeyData::CommandStopActor(v) => { + v5::ActorCommandKeyData::CommandStopActor(convert_command_stop_actor_v4_to_v5(v)?) + } + }) +} + +pub fn convert_message_id_v4_to_v5(x: v4::MessageId) -> Result { + Ok(v5::MessageId { + gateway_id: x.gateway_id, + request_id: x.request_id, + message_index: x.message_index, + }) +} + +pub fn convert_to_envoy_request_start_v4_to_v5( + x: v4::ToEnvoyRequestStart, +) -> Result { + Ok(v5::ToEnvoyRequestStart { + actor_id: x.actor_id, + method: x.method, + path: x.path, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_envoy_request_chunk_v4_to_v5( + x: v4::ToEnvoyRequestChunk, +) -> Result { + Ok(v5::ToEnvoyRequestChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_rivet_response_start_v4_to_v5( + x: v4::ToRivetResponseStart, +) -> Result { + Ok(v5::ToRivetResponseStart { + status: x.status, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_rivet_response_chunk_v4_to_v5( + x: v4::ToRivetResponseChunk, +) -> Result { + Ok(v5::ToRivetResponseChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_envoy_web_socket_open_v4_to_v5( + x: v4::ToEnvoyWebSocketOpen, +) -> Result { + Ok(v5::ToEnvoyWebSocketOpen { + actor_id: x.actor_id, + path: x.path, + headers: x.headers, + }) +} + +pub fn convert_to_envoy_web_socket_message_v4_to_v5( + x: v4::ToEnvoyWebSocketMessage, +) -> Result { + Ok(v5::ToEnvoyWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_envoy_web_socket_close_v4_to_v5( + x: v4::ToEnvoyWebSocketClose, +) -> Result { + Ok(v5::ToEnvoyWebSocketClose { + code: x.code, + reason: x.reason, + }) +} + +pub fn convert_to_rivet_web_socket_open_v4_to_v5( + x: v4::ToRivetWebSocketOpen, +) -> Result { + Ok(v5::ToRivetWebSocketOpen { + can_hibernate: x.can_hibernate, + }) +} + +pub fn convert_to_rivet_web_socket_message_v4_to_v5( + x: v4::ToRivetWebSocketMessage, +) -> Result { + Ok(v5::ToRivetWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_rivet_web_socket_message_ack_v4_to_v5( + x: v4::ToRivetWebSocketMessageAck, +) -> Result { + Ok(v5::ToRivetWebSocketMessageAck { index: x.index }) +} + +pub fn convert_to_rivet_web_socket_close_v4_to_v5( + x: v4::ToRivetWebSocketClose, +) -> Result { + Ok(v5::ToRivetWebSocketClose { + code: x.code, + reason: x.reason, + hibernate: x.hibernate, + }) +} + +pub fn convert_to_rivet_tunnel_message_kind_v4_to_v5( + x: v4::ToRivetTunnelMessageKind, +) -> Result { + Ok(match x { + v4::ToRivetTunnelMessageKind::ToRivetResponseStart(v) => { + v5::ToRivetTunnelMessageKind::ToRivetResponseStart( + convert_to_rivet_response_start_v4_to_v5(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetResponseChunk(v) => { + v5::ToRivetTunnelMessageKind::ToRivetResponseChunk( + convert_to_rivet_response_chunk_v4_to_v5(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetResponseAbort => { + v5::ToRivetTunnelMessageKind::ToRivetResponseAbort + } + v4::ToRivetTunnelMessageKind::ToRivetWebSocketOpen(v) => { + v5::ToRivetTunnelMessageKind::ToRivetWebSocketOpen( + convert_to_rivet_web_socket_open_v4_to_v5(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetWebSocketMessage(v) => { + v5::ToRivetTunnelMessageKind::ToRivetWebSocketMessage( + convert_to_rivet_web_socket_message_v4_to_v5(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck(v) => { + v5::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck( + convert_to_rivet_web_socket_message_ack_v4_to_v5(v)?, + ) + } + v4::ToRivetTunnelMessageKind::ToRivetWebSocketClose(v) => { + v5::ToRivetTunnelMessageKind::ToRivetWebSocketClose( + convert_to_rivet_web_socket_close_v4_to_v5(v)?, + ) + } + }) +} + +pub fn convert_to_rivet_tunnel_message_v4_to_v5( + x: v4::ToRivetTunnelMessage, +) -> Result { + Ok(v5::ToRivetTunnelMessage { + message_id: convert_message_id_v4_to_v5(x.message_id)?, + message_kind: convert_to_rivet_tunnel_message_kind_v4_to_v5(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_tunnel_message_kind_v4_to_v5( + x: v4::ToEnvoyTunnelMessageKind, +) -> Result { + Ok(match x { + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart(v) => { + v5::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart( + convert_to_envoy_request_start_v4_to_v5(v)?, + ) + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk(v) => { + v5::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk( + convert_to_envoy_request_chunk_v4_to_v5(v)?, + ) + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort => { + v5::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen(v) => { + v5::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen( + convert_to_envoy_web_socket_open_v4_to_v5(v)?, + ) + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage(v) => { + v5::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage( + convert_to_envoy_web_socket_message_v4_to_v5(v)?, + ) + } + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose(v) => { + v5::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose( + convert_to_envoy_web_socket_close_v4_to_v5(v)?, + ) + } + }) +} + +pub fn convert_to_envoy_tunnel_message_v4_to_v5( + x: v4::ToEnvoyTunnelMessage, +) -> Result { + Ok(v5::ToEnvoyTunnelMessage { + message_id: convert_message_id_v4_to_v5(x.message_id)?, + message_kind: convert_to_envoy_tunnel_message_kind_v4_to_v5(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_ping_v4_to_v5(x: v4::ToEnvoyPing) -> Result { + Ok(v5::ToEnvoyPing { ts: x.ts }) +} + +pub fn convert_to_rivet_metadata_v4_to_v5(x: v4::ToRivetMetadata) -> Result { + Ok(v5::ToRivetMetadata { + prepopulate_actor_names: x + .prepopulate_actor_names + .map(|v| { + v.into_iter() + .map(|(k, v)| -> Result<_> { Ok((k, convert_actor_name_v4_to_v5(v)?)) }) + .collect::>() + }) + .transpose()?, + metadata: x.metadata, + }) +} + +pub fn convert_to_rivet_events_v4_to_v5(x: v4::ToRivetEvents) -> Result { + Ok(x.into_iter() + .map(|v| convert_event_wrapper_v4_to_v5(v)) + .collect::>>()?) +} + +pub fn convert_to_rivet_ack_commands_v4_to_v5( + x: v4::ToRivetAckCommands, +) -> Result { + Ok(v5::ToRivetAckCommands { + last_command_checkpoints: x + .last_command_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v4_to_v5(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_rivet_pong_v4_to_v5(x: v4::ToRivetPong) -> Result { + Ok(v5::ToRivetPong { ts: x.ts }) +} + +pub fn convert_to_rivet_kv_request_v4_to_v5( + x: v4::ToRivetKvRequest, +) -> Result { + Ok(v5::ToRivetKvRequest { + actor_id: x.actor_id, + request_id: x.request_id, + data: convert_kv_request_data_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_get_pages_request_v4_to_v5( + x: v4::ToRivetSqliteGetPagesRequest, +) -> Result { + Ok(v5::ToRivetSqliteGetPagesRequest { + request_id: x.request_id, + data: convert_sqlite_get_pages_request_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_commit_request_v4_to_v5( + x: v4::ToRivetSqliteCommitRequest, +) -> Result { + Ok(v5::ToRivetSqliteCommitRequest { + request_id: x.request_id, + data: convert_sqlite_commit_request_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_exec_request_v4_to_v5( + x: v4::ToRivetSqliteExecRequest, +) -> Result { + Ok(v5::ToRivetSqliteExecRequest { + request_id: x.request_id, + data: convert_sqlite_exec_request_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_execute_request_v4_to_v5( + x: v4::ToRivetSqliteExecuteRequest, +) -> Result { + Ok(v5::ToRivetSqliteExecuteRequest { + request_id: x.request_id, + data: convert_sqlite_execute_request_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_rivet_v4_to_v5(x: v4::ToRivet) -> Result { + Ok(match x { + v4::ToRivet::ToRivetMetadata(v) => { + v5::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v4_to_v5(v)?) + } + v4::ToRivet::ToRivetEvents(v) => { + v5::ToRivet::ToRivetEvents(convert_to_rivet_events_v4_to_v5(v)?) + } + v4::ToRivet::ToRivetAckCommands(v) => { + v5::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v4_to_v5(v)?) + } + v4::ToRivet::ToRivetStopping => v5::ToRivet::ToRivetStopping, + v4::ToRivet::ToRivetPong(v) => v5::ToRivet::ToRivetPong(convert_to_rivet_pong_v4_to_v5(v)?), + v4::ToRivet::ToRivetKvRequest(v) => { + v5::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v4_to_v5(v)?) + } + v4::ToRivet::ToRivetTunnelMessage(v) => { + v5::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v4_to_v5(v)?) + } + v4::ToRivet::ToRivetSqliteGetPagesRequest(v) => v5::ToRivet::ToRivetSqliteGetPagesRequest( + convert_to_rivet_sqlite_get_pages_request_v4_to_v5(v)?, + ), + v4::ToRivet::ToRivetSqliteCommitRequest(v) => v5::ToRivet::ToRivetSqliteCommitRequest( + convert_to_rivet_sqlite_commit_request_v4_to_v5(v)?, + ), + v4::ToRivet::ToRivetSqliteExecRequest(v) => { + v5::ToRivet::ToRivetSqliteExecRequest(convert_to_rivet_sqlite_exec_request_v4_to_v5(v)?) + } + v4::ToRivet::ToRivetSqliteExecuteRequest(v) => v5::ToRivet::ToRivetSqliteExecuteRequest( + convert_to_rivet_sqlite_execute_request_v4_to_v5(v)?, + ), + }) +} + +pub fn convert_protocol_metadata_v4_to_v5(x: v4::ProtocolMetadata) -> Result { + Ok(v5::ProtocolMetadata { + envoy_lost_threshold: x.envoy_lost_threshold, + actor_stop_threshold: x.actor_stop_threshold, + max_response_payload_size: x.max_response_payload_size, + }) +} + +pub fn convert_to_envoy_init_v4_to_v5(x: v4::ToEnvoyInit) -> Result { + Ok(v5::ToEnvoyInit { + metadata: convert_protocol_metadata_v4_to_v5(x.metadata)?, + }) +} + +pub fn convert_to_envoy_commands_v4_to_v5(x: v4::ToEnvoyCommands) -> Result { + Ok(x.into_iter() + .map(|v| convert_command_wrapper_v4_to_v5(v)) + .collect::>>()?) +} + +pub fn convert_to_envoy_ack_events_v4_to_v5( + x: v4::ToEnvoyAckEvents, +) -> Result { + Ok(v5::ToEnvoyAckEvents { + last_event_checkpoints: x + .last_event_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v4_to_v5(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_envoy_kv_response_v4_to_v5( + x: v4::ToEnvoyKvResponse, +) -> Result { + Ok(v5::ToEnvoyKvResponse { + request_id: x.request_id, + data: convert_kv_response_data_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_get_pages_response_v4_to_v5( + x: v4::ToEnvoySqliteGetPagesResponse, +) -> Result { + Ok(v5::ToEnvoySqliteGetPagesResponse { + request_id: x.request_id, + data: convert_sqlite_get_pages_response_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_commit_response_v4_to_v5( + x: v4::ToEnvoySqliteCommitResponse, +) -> Result { + Ok(v5::ToEnvoySqliteCommitResponse { + request_id: x.request_id, + data: convert_sqlite_commit_response_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_exec_response_v4_to_v5( + x: v4::ToEnvoySqliteExecResponse, +) -> Result { + Ok(v5::ToEnvoySqliteExecResponse { + request_id: x.request_id, + data: convert_sqlite_exec_response_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_execute_response_v4_to_v5( + x: v4::ToEnvoySqliteExecuteResponse, +) -> Result { + Ok(v5::ToEnvoySqliteExecuteResponse { + request_id: x.request_id, + data: convert_sqlite_execute_response_v4_to_v5(x.data)?, + }) +} + +pub fn convert_to_envoy_v4_to_v5(x: v4::ToEnvoy) -> Result { + Ok(match x { + v4::ToEnvoy::ToEnvoyInit(v) => v5::ToEnvoy::ToEnvoyInit(convert_to_envoy_init_v4_to_v5(v)?), + v4::ToEnvoy::ToEnvoyCommands(v) => { + v5::ToEnvoy::ToEnvoyCommands(convert_to_envoy_commands_v4_to_v5(v)?) + } + v4::ToEnvoy::ToEnvoyAckEvents(v) => { + v5::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v4_to_v5(v)?) + } + v4::ToEnvoy::ToEnvoyKvResponse(v) => { + v5::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v4_to_v5(v)?) + } + v4::ToEnvoy::ToEnvoyTunnelMessage(v) => { + v5::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v4_to_v5(v)?) + } + v4::ToEnvoy::ToEnvoyPing(v) => v5::ToEnvoy::ToEnvoyPing(convert_to_envoy_ping_v4_to_v5(v)?), + v4::ToEnvoy::ToEnvoySqliteGetPagesResponse(v) => { + v5::ToEnvoy::ToEnvoySqliteGetPagesResponse( + convert_to_envoy_sqlite_get_pages_response_v4_to_v5(v)?, + ) + } + v4::ToEnvoy::ToEnvoySqliteCommitResponse(v) => v5::ToEnvoy::ToEnvoySqliteCommitResponse( + convert_to_envoy_sqlite_commit_response_v4_to_v5(v)?, + ), + v4::ToEnvoy::ToEnvoySqliteExecResponse(v) => v5::ToEnvoy::ToEnvoySqliteExecResponse( + convert_to_envoy_sqlite_exec_response_v4_to_v5(v)?, + ), + v4::ToEnvoy::ToEnvoySqliteExecuteResponse(v) => v5::ToEnvoy::ToEnvoySqliteExecuteResponse( + convert_to_envoy_sqlite_execute_response_v4_to_v5(v)?, + ), + }) +} + +pub fn convert_to_envoy_conn_ping_v4_to_v5(x: v4::ToEnvoyConnPing) -> Result { + Ok(v5::ToEnvoyConnPing { + gateway_id: x.gateway_id, + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_envoy_conn_v4_to_v5(x: v4::ToEnvoyConn) -> Result { + Ok(match x { + v4::ToEnvoyConn::ToEnvoyConnPing(v) => { + v5::ToEnvoyConn::ToEnvoyConnPing(convert_to_envoy_conn_ping_v4_to_v5(v)?) + } + v4::ToEnvoyConn::ToEnvoyConnClose => v5::ToEnvoyConn::ToEnvoyConnClose, + v4::ToEnvoyConn::ToEnvoyCommands(v) => { + v5::ToEnvoyConn::ToEnvoyCommands(convert_to_envoy_commands_v4_to_v5(v)?) + } + v4::ToEnvoyConn::ToEnvoyAckEvents(v) => { + v5::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v4_to_v5(v)?) + } + v4::ToEnvoyConn::ToEnvoyTunnelMessage(v) => { + v5::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v4_to_v5(v)?) + } + }) +} + +pub fn convert_to_gateway_pong_v4_to_v5(x: v4::ToGatewayPong) -> Result { + Ok(v5::ToGatewayPong { + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_gateway_v4_to_v5(x: v4::ToGateway) -> Result { + Ok(match x { + v4::ToGateway::ToGatewayPong(v) => { + v5::ToGateway::ToGatewayPong(convert_to_gateway_pong_v4_to_v5(v)?) + } + v4::ToGateway::ToRivetTunnelMessage(v) => { + v5::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v4_to_v5(v)?) + } + }) +} + +pub fn convert_to_outbound_actor_start_v4_to_v5( + x: v4::ToOutboundActorStart, +) -> Result { + Ok(v5::ToOutboundActorStart { + namespace_id: x.namespace_id, + pool_name: x.pool_name, + checkpoint: convert_actor_checkpoint_v4_to_v5(x.checkpoint)?, + actor_config: convert_actor_config_v4_to_v5(x.actor_config)?, + }) +} + +pub fn convert_to_outbound_v4_to_v5(x: v4::ToOutbound) -> Result { + Ok(match x { + v4::ToOutbound::ToOutboundActorStart(v) => { + v5::ToOutbound::ToOutboundActorStart(convert_to_outbound_actor_start_v4_to_v5(v)?) + } + }) +} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned/v5_to_v4.rs b/engine/sdks/rust/envoy-protocol/src/versioned/v5_to_v4.rs new file mode 100644 index 0000000000..649b254dd2 --- /dev/null +++ b/engine/sdks/rust/envoy-protocol/src/versioned/v5_to_v4.rs @@ -0,0 +1,1093 @@ +// @generated initial scaffold by scripts/vbare-gen-converters +// from: v5.bare, to: v4.bare +// Replace each todo!() with the migration semantics, then drop the @generated marker. + +#![allow(dead_code, unused_variables)] + +use anyhow::Result; + +use crate::generated::{v4, v5}; + +pub fn convert_kv_metadata_v5_to_v4(x: v5::KvMetadata) -> Result { + Ok(v4::KvMetadata { + version: x.version, + update_ts: x.update_ts, + }) +} + +pub fn convert_kv_list_range_query_v5_to_v4( + x: v5::KvListRangeQuery, +) -> Result { + Ok(v4::KvListRangeQuery { + start: x.start, + end: x.end, + exclusive: x.exclusive, + }) +} + +pub fn convert_kv_list_prefix_query_v5_to_v4( + x: v5::KvListPrefixQuery, +) -> Result { + Ok(v4::KvListPrefixQuery { key: x.key }) +} + +pub fn convert_kv_list_query_v5_to_v4(x: v5::KvListQuery) -> Result { + Ok(match x { + v5::KvListQuery::KvListAllQuery => v4::KvListQuery::KvListAllQuery, + v5::KvListQuery::KvListRangeQuery(v) => { + v4::KvListQuery::KvListRangeQuery(convert_kv_list_range_query_v5_to_v4(v)?) + } + v5::KvListQuery::KvListPrefixQuery(v) => { + v4::KvListQuery::KvListPrefixQuery(convert_kv_list_prefix_query_v5_to_v4(v)?) + } + }) +} + +pub fn convert_kv_get_request_v5_to_v4(x: v5::KvGetRequest) -> Result { + Ok(v4::KvGetRequest { keys: x.keys }) +} + +pub fn convert_kv_list_request_v5_to_v4(x: v5::KvListRequest) -> Result { + Ok(v4::KvListRequest { + query: convert_kv_list_query_v5_to_v4(x.query)?, + reverse: x.reverse, + limit: x.limit, + }) +} + +pub fn convert_kv_put_request_v5_to_v4(x: v5::KvPutRequest) -> Result { + Ok(v4::KvPutRequest { + keys: x.keys, + values: x.values, + }) +} + +pub fn convert_kv_delete_request_v5_to_v4(x: v5::KvDeleteRequest) -> Result { + Ok(v4::KvDeleteRequest { keys: x.keys }) +} + +pub fn convert_kv_delete_range_request_v5_to_v4( + x: v5::KvDeleteRangeRequest, +) -> Result { + Ok(v4::KvDeleteRangeRequest { + start: x.start, + end: x.end, + }) +} + +pub fn convert_kv_error_response_v5_to_v4(x: v5::KvErrorResponse) -> Result { + Ok(v4::KvErrorResponse { message: x.message }) +} + +pub fn convert_kv_get_response_v5_to_v4(x: v5::KvGetResponse) -> Result { + Ok(v4::KvGetResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v5_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_list_response_v5_to_v4(x: v5::KvListResponse) -> Result { + Ok(v4::KvListResponse { + keys: x.keys, + values: x.values, + metadata: x + .metadata + .into_iter() + .map(|v| convert_kv_metadata_v5_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_kv_request_data_v5_to_v4(x: v5::KvRequestData) -> Result { + Ok(match x { + v5::KvRequestData::KvGetRequest(v) => { + v4::KvRequestData::KvGetRequest(convert_kv_get_request_v5_to_v4(v)?) + } + v5::KvRequestData::KvListRequest(v) => { + v4::KvRequestData::KvListRequest(convert_kv_list_request_v5_to_v4(v)?) + } + v5::KvRequestData::KvPutRequest(v) => { + v4::KvRequestData::KvPutRequest(convert_kv_put_request_v5_to_v4(v)?) + } + v5::KvRequestData::KvDeleteRequest(v) => { + v4::KvRequestData::KvDeleteRequest(convert_kv_delete_request_v5_to_v4(v)?) + } + v5::KvRequestData::KvDeleteRangeRequest(v) => { + v4::KvRequestData::KvDeleteRangeRequest(convert_kv_delete_range_request_v5_to_v4(v)?) + } + v5::KvRequestData::KvDropRequest => v4::KvRequestData::KvDropRequest, + }) +} + +pub fn convert_kv_response_data_v5_to_v4(x: v5::KvResponseData) -> Result { + Ok(match x { + v5::KvResponseData::KvErrorResponse(v) => { + v4::KvResponseData::KvErrorResponse(convert_kv_error_response_v5_to_v4(v)?) + } + v5::KvResponseData::KvGetResponse(v) => { + v4::KvResponseData::KvGetResponse(convert_kv_get_response_v5_to_v4(v)?) + } + v5::KvResponseData::KvListResponse(v) => { + v4::KvResponseData::KvListResponse(convert_kv_list_response_v5_to_v4(v)?) + } + v5::KvResponseData::KvPutResponse => v4::KvResponseData::KvPutResponse, + v5::KvResponseData::KvDeleteResponse => v4::KvResponseData::KvDeleteResponse, + v5::KvResponseData::KvDropResponse => v4::KvResponseData::KvDropResponse, + }) +} + +pub fn convert_sqlite_dirty_page_v5_to_v4(x: v5::SqliteDirtyPage) -> Result { + Ok(v4::SqliteDirtyPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_fetched_page_v5_to_v4( + x: v5::SqliteFetchedPage, +) -> Result { + Ok(v4::SqliteFetchedPage { + pgno: x.pgno, + bytes: x.bytes, + }) +} + +pub fn convert_sqlite_get_pages_request_v5_to_v4( + x: v5::SqliteGetPagesRequest, +) -> Result { + Ok(v4::SqliteGetPagesRequest { + actor_id: x.actor_id, + pgnos: x.pgnos, + expected_generation: x.expected_generation, + expected_head_txid: x.expected_head_txid, + }) +} + +pub fn convert_sqlite_get_pages_ok_v5_to_v4( + x: v5::SqliteGetPagesOk, +) -> Result { + Ok(v4::SqliteGetPagesOk { + pages: x + .pages + .into_iter() + .map(|v| convert_sqlite_fetched_page_v5_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_sqlite_error_response_v5_to_v4( + x: v5::SqliteErrorResponse, +) -> Result { + Ok(v4::SqliteErrorResponse { message: x.message }) +} + +pub fn convert_sqlite_get_pages_response_v5_to_v4( + x: v5::SqliteGetPagesResponse, +) -> Result { + Ok(match x { + v5::SqliteGetPagesResponse::SqliteGetPagesOk(v) => { + v4::SqliteGetPagesResponse::SqliteGetPagesOk(convert_sqlite_get_pages_ok_v5_to_v4(v)?) + } + v5::SqliteGetPagesResponse::SqliteErrorResponse(v) => { + v4::SqliteGetPagesResponse::SqliteErrorResponse(convert_sqlite_error_response_v5_to_v4( + v, + )?) + } + }) +} + +pub fn convert_sqlite_commit_request_v5_to_v4( + x: v5::SqliteCommitRequest, +) -> Result { + Ok(v4::SqliteCommitRequest { + actor_id: x.actor_id, + dirty_pages: x + .dirty_pages + .into_iter() + .map(|v| convert_sqlite_dirty_page_v5_to_v4(v)) + .collect::>>()?, + db_size_pages: x.db_size_pages, + now_ms: x.now_ms, + expected_generation: x.expected_generation, + expected_head_txid: x.expected_head_txid, + }) +} + +pub fn convert_sqlite_commit_response_v5_to_v4( + x: v5::SqliteCommitResponse, +) -> Result { + Ok(match x { + v5::SqliteCommitResponse::SqliteCommitOk(_) => { + // v4 had no head_txid; drop the field on the way down. + v4::SqliteCommitResponse::SqliteCommitOk + } + v5::SqliteCommitResponse::SqliteErrorResponse(v) => { + v4::SqliteCommitResponse::SqliteErrorResponse(convert_sqlite_error_response_v5_to_v4( + v, + )?) + } + }) +} + +pub fn convert_sqlite_value_integer_v5_to_v4( + x: v5::SqliteValueInteger, +) -> Result { + Ok(v4::SqliteValueInteger { value: x.value }) +} + +pub fn convert_sqlite_value_float_v5_to_v4( + x: v5::SqliteValueFloat, +) -> Result { + Ok(v4::SqliteValueFloat { value: x.value }) +} + +pub fn convert_sqlite_value_text_v5_to_v4(x: v5::SqliteValueText) -> Result { + Ok(v4::SqliteValueText { value: x.value }) +} + +pub fn convert_sqlite_value_blob_v5_to_v4(x: v5::SqliteValueBlob) -> Result { + Ok(v4::SqliteValueBlob { value: x.value }) +} + +pub fn convert_sqlite_bind_param_v5_to_v4(x: v5::SqliteBindParam) -> Result { + Ok(match x { + v5::SqliteBindParam::SqliteValueNull => v4::SqliteBindParam::SqliteValueNull, + v5::SqliteBindParam::SqliteValueInteger(v) => { + v4::SqliteBindParam::SqliteValueInteger(convert_sqlite_value_integer_v5_to_v4(v)?) + } + v5::SqliteBindParam::SqliteValueFloat(v) => { + v4::SqliteBindParam::SqliteValueFloat(convert_sqlite_value_float_v5_to_v4(v)?) + } + v5::SqliteBindParam::SqliteValueText(v) => { + v4::SqliteBindParam::SqliteValueText(convert_sqlite_value_text_v5_to_v4(v)?) + } + v5::SqliteBindParam::SqliteValueBlob(v) => { + v4::SqliteBindParam::SqliteValueBlob(convert_sqlite_value_blob_v5_to_v4(v)?) + } + }) +} + +pub fn convert_sqlite_column_value_v5_to_v4( + x: v5::SqliteColumnValue, +) -> Result { + Ok(match x { + v5::SqliteColumnValue::SqliteValueNull => v4::SqliteColumnValue::SqliteValueNull, + v5::SqliteColumnValue::SqliteValueInteger(v) => { + v4::SqliteColumnValue::SqliteValueInteger(convert_sqlite_value_integer_v5_to_v4(v)?) + } + v5::SqliteColumnValue::SqliteValueFloat(v) => { + v4::SqliteColumnValue::SqliteValueFloat(convert_sqlite_value_float_v5_to_v4(v)?) + } + v5::SqliteColumnValue::SqliteValueText(v) => { + v4::SqliteColumnValue::SqliteValueText(convert_sqlite_value_text_v5_to_v4(v)?) + } + v5::SqliteColumnValue::SqliteValueBlob(v) => { + v4::SqliteColumnValue::SqliteValueBlob(convert_sqlite_value_blob_v5_to_v4(v)?) + } + }) +} + +pub fn convert_sqlite_query_result_v5_to_v4( + x: v5::SqliteQueryResult, +) -> Result { + Ok(v4::SqliteQueryResult { + columns: x.columns, + rows: x + .rows + .into_iter() + .map(|v| { + v.into_iter() + .map(|v| convert_sqlite_column_value_v5_to_v4(v)) + .collect::>>() + }) + .collect::>>()?, + }) +} + +pub fn convert_sqlite_execute_result_v5_to_v4( + x: v5::SqliteExecuteResult, +) -> Result { + Ok(v4::SqliteExecuteResult { + columns: x.columns, + rows: x + .rows + .into_iter() + .map(|v| { + v.into_iter() + .map(|v| convert_sqlite_column_value_v5_to_v4(v)) + .collect::>>() + }) + .collect::>>()?, + changes: x.changes, + last_insert_row_id: x.last_insert_row_id, + }) +} + +pub fn convert_sqlite_exec_request_v5_to_v4( + x: v5::SqliteExecRequest, +) -> Result { + Ok(v4::SqliteExecRequest { + namespace_id: x.namespace_id, + actor_id: x.actor_id, + generation: x.generation, + sql: x.sql, + }) +} + +pub fn convert_sqlite_execute_request_v5_to_v4( + x: v5::SqliteExecuteRequest, +) -> Result { + Ok(v4::SqliteExecuteRequest { + namespace_id: x.namespace_id, + actor_id: x.actor_id, + generation: x.generation, + sql: x.sql, + params: x + .params + .map(|v| { + v.into_iter() + .map(|v| convert_sqlite_bind_param_v5_to_v4(v)) + .collect::>>() + }) + .transpose()?, + }) +} + +pub fn convert_sqlite_exec_ok_v5_to_v4(x: v5::SqliteExecOk) -> Result { + Ok(v4::SqliteExecOk { + result: convert_sqlite_query_result_v5_to_v4(x.result)?, + }) +} + +pub fn convert_sqlite_execute_ok_v5_to_v4(x: v5::SqliteExecuteOk) -> Result { + Ok(v4::SqliteExecuteOk { + result: convert_sqlite_execute_result_v5_to_v4(x.result)?, + }) +} + +pub fn convert_sqlite_exec_response_v5_to_v4( + x: v5::SqliteExecResponse, +) -> Result { + Ok(match x { + v5::SqliteExecResponse::SqliteExecOk(v) => { + v4::SqliteExecResponse::SqliteExecOk(convert_sqlite_exec_ok_v5_to_v4(v)?) + } + v5::SqliteExecResponse::SqliteErrorResponse(v) => { + v4::SqliteExecResponse::SqliteErrorResponse(convert_sqlite_error_response_v5_to_v4(v)?) + } + }) +} + +pub fn convert_sqlite_execute_response_v5_to_v4( + x: v5::SqliteExecuteResponse, +) -> Result { + Ok(match x { + v5::SqliteExecuteResponse::SqliteExecuteOk(v) => { + v4::SqliteExecuteResponse::SqliteExecuteOk(convert_sqlite_execute_ok_v5_to_v4(v)?) + } + v5::SqliteExecuteResponse::SqliteErrorResponse(v) => { + v4::SqliteExecuteResponse::SqliteErrorResponse(convert_sqlite_error_response_v5_to_v4( + v, + )?) + } + }) +} + +pub fn convert_stop_code_v5_to_v4(x: v5::StopCode) -> Result { + Ok(match x { + v5::StopCode::Ok => v4::StopCode::Ok, + v5::StopCode::Error => v4::StopCode::Error, + }) +} + +pub fn convert_actor_name_v5_to_v4(x: v5::ActorName) -> Result { + Ok(v4::ActorName { + metadata: x.metadata, + }) +} + +pub fn convert_actor_config_v5_to_v4(x: v5::ActorConfig) -> Result { + Ok(v4::ActorConfig { + name: x.name, + key: x.key, + create_ts: x.create_ts, + input: x.input, + }) +} + +pub fn convert_actor_checkpoint_v5_to_v4(x: v5::ActorCheckpoint) -> Result { + Ok(v4::ActorCheckpoint { + actor_id: x.actor_id, + generation: x.generation, + index: x.index, + }) +} + +pub fn convert_actor_intent_v5_to_v4(x: v5::ActorIntent) -> Result { + Ok(match x { + v5::ActorIntent::ActorIntentSleep => v4::ActorIntent::ActorIntentSleep, + v5::ActorIntent::ActorIntentStop => v4::ActorIntent::ActorIntentStop, + }) +} + +pub fn convert_actor_state_stopped_v5_to_v4( + x: v5::ActorStateStopped, +) -> Result { + Ok(v4::ActorStateStopped { + code: convert_stop_code_v5_to_v4(x.code)?, + message: x.message, + }) +} + +pub fn convert_actor_state_v5_to_v4(x: v5::ActorState) -> Result { + Ok(match x { + v5::ActorState::ActorStateRunning => v4::ActorState::ActorStateRunning, + v5::ActorState::ActorStateStopped(v) => { + v4::ActorState::ActorStateStopped(convert_actor_state_stopped_v5_to_v4(v)?) + } + }) +} + +pub fn convert_event_actor_intent_v5_to_v4( + x: v5::EventActorIntent, +) -> Result { + Ok(v4::EventActorIntent { + intent: convert_actor_intent_v5_to_v4(x.intent)?, + }) +} + +pub fn convert_event_actor_state_update_v5_to_v4( + x: v5::EventActorStateUpdate, +) -> Result { + Ok(v4::EventActorStateUpdate { + state: convert_actor_state_v5_to_v4(x.state)?, + }) +} + +pub fn convert_event_actor_set_alarm_v5_to_v4( + x: v5::EventActorSetAlarm, +) -> Result { + Ok(v4::EventActorSetAlarm { + alarm_ts: x.alarm_ts, + }) +} + +pub fn convert_event_v5_to_v4(x: v5::Event) -> Result { + Ok(match x { + v5::Event::EventActorIntent(v) => { + v4::Event::EventActorIntent(convert_event_actor_intent_v5_to_v4(v)?) + } + v5::Event::EventActorStateUpdate(v) => { + v4::Event::EventActorStateUpdate(convert_event_actor_state_update_v5_to_v4(v)?) + } + v5::Event::EventActorSetAlarm(v) => { + v4::Event::EventActorSetAlarm(convert_event_actor_set_alarm_v5_to_v4(v)?) + } + }) +} + +pub fn convert_event_wrapper_v5_to_v4(x: v5::EventWrapper) -> Result { + Ok(v4::EventWrapper { + checkpoint: convert_actor_checkpoint_v5_to_v4(x.checkpoint)?, + inner: convert_event_v5_to_v4(x.inner)?, + }) +} + +pub fn convert_preloaded_kv_entry_v5_to_v4( + x: v5::PreloadedKvEntry, +) -> Result { + Ok(v4::PreloadedKvEntry { + key: x.key, + value: x.value, + metadata: convert_kv_metadata_v5_to_v4(x.metadata)?, + }) +} + +pub fn convert_preloaded_kv_v5_to_v4(x: v5::PreloadedKv) -> Result { + Ok(v4::PreloadedKv { + entries: x + .entries + .into_iter() + .map(|v| convert_preloaded_kv_entry_v5_to_v4(v)) + .collect::>>()?, + requested_get_keys: x.requested_get_keys, + requested_prefixes: x.requested_prefixes, + }) +} + +pub fn convert_hibernating_request_v5_to_v4( + x: v5::HibernatingRequest, +) -> Result { + Ok(v4::HibernatingRequest { + gateway_id: x.gateway_id, + request_id: x.request_id, + }) +} + +pub fn convert_command_start_actor_v5_to_v4( + x: v5::CommandStartActor, +) -> Result { + Ok(v4::CommandStartActor { + config: convert_actor_config_v5_to_v4(x.config)?, + hibernating_requests: x + .hibernating_requests + .into_iter() + .map(|v| convert_hibernating_request_v5_to_v4(v)) + .collect::>>()?, + preloaded_kv: x + .preloaded_kv + .map(|v| convert_preloaded_kv_v5_to_v4(v)) + .transpose()?, + }) +} + +pub fn convert_stop_actor_reason_v5_to_v4(x: v5::StopActorReason) -> Result { + Ok(match x { + v5::StopActorReason::SleepIntent => v4::StopActorReason::SleepIntent, + v5::StopActorReason::StopIntent => v4::StopActorReason::StopIntent, + v5::StopActorReason::Destroy => v4::StopActorReason::Destroy, + v5::StopActorReason::GoingAway => v4::StopActorReason::GoingAway, + v5::StopActorReason::Lost => v4::StopActorReason::Lost, + }) +} + +pub fn convert_command_stop_actor_v5_to_v4( + x: v5::CommandStopActor, +) -> Result { + Ok(v4::CommandStopActor { + reason: convert_stop_actor_reason_v5_to_v4(x.reason)?, + }) +} + +pub fn convert_command_v5_to_v4(x: v5::Command) -> Result { + Ok(match x { + v5::Command::CommandStartActor(v) => { + v4::Command::CommandStartActor(convert_command_start_actor_v5_to_v4(v)?) + } + v5::Command::CommandStopActor(v) => { + v4::Command::CommandStopActor(convert_command_stop_actor_v5_to_v4(v)?) + } + }) +} + +pub fn convert_command_wrapper_v5_to_v4(x: v5::CommandWrapper) -> Result { + Ok(v4::CommandWrapper { + checkpoint: convert_actor_checkpoint_v5_to_v4(x.checkpoint)?, + inner: convert_command_v5_to_v4(x.inner)?, + }) +} + +pub fn convert_actor_command_key_data_v5_to_v4( + x: v5::ActorCommandKeyData, +) -> Result { + Ok(match x { + v5::ActorCommandKeyData::CommandStartActor(v) => { + v4::ActorCommandKeyData::CommandStartActor(convert_command_start_actor_v5_to_v4(v)?) + } + v5::ActorCommandKeyData::CommandStopActor(v) => { + v4::ActorCommandKeyData::CommandStopActor(convert_command_stop_actor_v5_to_v4(v)?) + } + }) +} + +pub fn convert_message_id_v5_to_v4(x: v5::MessageId) -> Result { + Ok(v4::MessageId { + gateway_id: x.gateway_id, + request_id: x.request_id, + message_index: x.message_index, + }) +} + +pub fn convert_to_envoy_request_start_v5_to_v4( + x: v5::ToEnvoyRequestStart, +) -> Result { + Ok(v4::ToEnvoyRequestStart { + actor_id: x.actor_id, + method: x.method, + path: x.path, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_envoy_request_chunk_v5_to_v4( + x: v5::ToEnvoyRequestChunk, +) -> Result { + Ok(v4::ToEnvoyRequestChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_rivet_response_start_v5_to_v4( + x: v5::ToRivetResponseStart, +) -> Result { + Ok(v4::ToRivetResponseStart { + status: x.status, + headers: x.headers, + body: x.body, + stream: x.stream, + }) +} + +pub fn convert_to_rivet_response_chunk_v5_to_v4( + x: v5::ToRivetResponseChunk, +) -> Result { + Ok(v4::ToRivetResponseChunk { + body: x.body, + finish: x.finish, + }) +} + +pub fn convert_to_envoy_web_socket_open_v5_to_v4( + x: v5::ToEnvoyWebSocketOpen, +) -> Result { + Ok(v4::ToEnvoyWebSocketOpen { + actor_id: x.actor_id, + path: x.path, + headers: x.headers, + }) +} + +pub fn convert_to_envoy_web_socket_message_v5_to_v4( + x: v5::ToEnvoyWebSocketMessage, +) -> Result { + Ok(v4::ToEnvoyWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_envoy_web_socket_close_v5_to_v4( + x: v5::ToEnvoyWebSocketClose, +) -> Result { + Ok(v4::ToEnvoyWebSocketClose { + code: x.code, + reason: x.reason, + }) +} + +pub fn convert_to_rivet_web_socket_open_v5_to_v4( + x: v5::ToRivetWebSocketOpen, +) -> Result { + Ok(v4::ToRivetWebSocketOpen { + can_hibernate: x.can_hibernate, + }) +} + +pub fn convert_to_rivet_web_socket_message_v5_to_v4( + x: v5::ToRivetWebSocketMessage, +) -> Result { + Ok(v4::ToRivetWebSocketMessage { + data: x.data, + binary: x.binary, + }) +} + +pub fn convert_to_rivet_web_socket_message_ack_v5_to_v4( + x: v5::ToRivetWebSocketMessageAck, +) -> Result { + Ok(v4::ToRivetWebSocketMessageAck { index: x.index }) +} + +pub fn convert_to_rivet_web_socket_close_v5_to_v4( + x: v5::ToRivetWebSocketClose, +) -> Result { + Ok(v4::ToRivetWebSocketClose { + code: x.code, + reason: x.reason, + hibernate: x.hibernate, + }) +} + +pub fn convert_to_rivet_tunnel_message_kind_v5_to_v4( + x: v5::ToRivetTunnelMessageKind, +) -> Result { + Ok(match x { + v5::ToRivetTunnelMessageKind::ToRivetResponseStart(v) => { + v4::ToRivetTunnelMessageKind::ToRivetResponseStart( + convert_to_rivet_response_start_v5_to_v4(v)?, + ) + } + v5::ToRivetTunnelMessageKind::ToRivetResponseChunk(v) => { + v4::ToRivetTunnelMessageKind::ToRivetResponseChunk( + convert_to_rivet_response_chunk_v5_to_v4(v)?, + ) + } + v5::ToRivetTunnelMessageKind::ToRivetResponseAbort => { + v4::ToRivetTunnelMessageKind::ToRivetResponseAbort + } + v5::ToRivetTunnelMessageKind::ToRivetWebSocketOpen(v) => { + v4::ToRivetTunnelMessageKind::ToRivetWebSocketOpen( + convert_to_rivet_web_socket_open_v5_to_v4(v)?, + ) + } + v5::ToRivetTunnelMessageKind::ToRivetWebSocketMessage(v) => { + v4::ToRivetTunnelMessageKind::ToRivetWebSocketMessage( + convert_to_rivet_web_socket_message_v5_to_v4(v)?, + ) + } + v5::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck(v) => { + v4::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck( + convert_to_rivet_web_socket_message_ack_v5_to_v4(v)?, + ) + } + v5::ToRivetTunnelMessageKind::ToRivetWebSocketClose(v) => { + v4::ToRivetTunnelMessageKind::ToRivetWebSocketClose( + convert_to_rivet_web_socket_close_v5_to_v4(v)?, + ) + } + }) +} + +pub fn convert_to_rivet_tunnel_message_v5_to_v4( + x: v5::ToRivetTunnelMessage, +) -> Result { + Ok(v4::ToRivetTunnelMessage { + message_id: convert_message_id_v5_to_v4(x.message_id)?, + message_kind: convert_to_rivet_tunnel_message_kind_v5_to_v4(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_tunnel_message_kind_v5_to_v4( + x: v5::ToEnvoyTunnelMessageKind, +) -> Result { + Ok(match x { + v5::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart( + convert_to_envoy_request_start_v5_to_v4(v)?, + ) + } + v5::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk( + convert_to_envoy_request_chunk_v5_to_v4(v)?, + ) + } + v5::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort + } + v5::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen( + convert_to_envoy_web_socket_open_v5_to_v4(v)?, + ) + } + v5::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage( + convert_to_envoy_web_socket_message_v5_to_v4(v)?, + ) + } + v5::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose(v) => { + v4::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose( + convert_to_envoy_web_socket_close_v5_to_v4(v)?, + ) + } + }) +} + +pub fn convert_to_envoy_tunnel_message_v5_to_v4( + x: v5::ToEnvoyTunnelMessage, +) -> Result { + Ok(v4::ToEnvoyTunnelMessage { + message_id: convert_message_id_v5_to_v4(x.message_id)?, + message_kind: convert_to_envoy_tunnel_message_kind_v5_to_v4(x.message_kind)?, + }) +} + +pub fn convert_to_envoy_ping_v5_to_v4(x: v5::ToEnvoyPing) -> Result { + Ok(v4::ToEnvoyPing { ts: x.ts }) +} + +pub fn convert_to_rivet_metadata_v5_to_v4(x: v5::ToRivetMetadata) -> Result { + Ok(v4::ToRivetMetadata { + prepopulate_actor_names: x + .prepopulate_actor_names + .map(|v| { + v.into_iter() + .map(|(k, v)| -> Result<_> { Ok((k, convert_actor_name_v5_to_v4(v)?)) }) + .collect::>() + }) + .transpose()?, + metadata: x.metadata, + }) +} + +pub fn convert_to_rivet_events_v5_to_v4(x: v5::ToRivetEvents) -> Result { + Ok(x.into_iter() + .map(|v| convert_event_wrapper_v5_to_v4(v)) + .collect::>>()?) +} + +pub fn convert_to_rivet_ack_commands_v5_to_v4( + x: v5::ToRivetAckCommands, +) -> Result { + Ok(v4::ToRivetAckCommands { + last_command_checkpoints: x + .last_command_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v5_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_rivet_pong_v5_to_v4(x: v5::ToRivetPong) -> Result { + Ok(v4::ToRivetPong { ts: x.ts }) +} + +pub fn convert_to_rivet_kv_request_v5_to_v4( + x: v5::ToRivetKvRequest, +) -> Result { + Ok(v4::ToRivetKvRequest { + actor_id: x.actor_id, + request_id: x.request_id, + data: convert_kv_request_data_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_get_pages_request_v5_to_v4( + x: v5::ToRivetSqliteGetPagesRequest, +) -> Result { + Ok(v4::ToRivetSqliteGetPagesRequest { + request_id: x.request_id, + data: convert_sqlite_get_pages_request_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_commit_request_v5_to_v4( + x: v5::ToRivetSqliteCommitRequest, +) -> Result { + Ok(v4::ToRivetSqliteCommitRequest { + request_id: x.request_id, + data: convert_sqlite_commit_request_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_exec_request_v5_to_v4( + x: v5::ToRivetSqliteExecRequest, +) -> Result { + Ok(v4::ToRivetSqliteExecRequest { + request_id: x.request_id, + data: convert_sqlite_exec_request_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_rivet_sqlite_execute_request_v5_to_v4( + x: v5::ToRivetSqliteExecuteRequest, +) -> Result { + Ok(v4::ToRivetSqliteExecuteRequest { + request_id: x.request_id, + data: convert_sqlite_execute_request_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_rivet_v5_to_v4(x: v5::ToRivet) -> Result { + Ok(match x { + v5::ToRivet::ToRivetMetadata(v) => { + v4::ToRivet::ToRivetMetadata(convert_to_rivet_metadata_v5_to_v4(v)?) + } + v5::ToRivet::ToRivetEvents(v) => { + v4::ToRivet::ToRivetEvents(convert_to_rivet_events_v5_to_v4(v)?) + } + v5::ToRivet::ToRivetAckCommands(v) => { + v4::ToRivet::ToRivetAckCommands(convert_to_rivet_ack_commands_v5_to_v4(v)?) + } + v5::ToRivet::ToRivetStopping => v4::ToRivet::ToRivetStopping, + v5::ToRivet::ToRivetPong(v) => v4::ToRivet::ToRivetPong(convert_to_rivet_pong_v5_to_v4(v)?), + v5::ToRivet::ToRivetKvRequest(v) => { + v4::ToRivet::ToRivetKvRequest(convert_to_rivet_kv_request_v5_to_v4(v)?) + } + v5::ToRivet::ToRivetTunnelMessage(v) => { + v4::ToRivet::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v5_to_v4(v)?) + } + v5::ToRivet::ToRivetSqliteGetPagesRequest(v) => v4::ToRivet::ToRivetSqliteGetPagesRequest( + convert_to_rivet_sqlite_get_pages_request_v5_to_v4(v)?, + ), + v5::ToRivet::ToRivetSqliteCommitRequest(v) => v4::ToRivet::ToRivetSqliteCommitRequest( + convert_to_rivet_sqlite_commit_request_v5_to_v4(v)?, + ), + v5::ToRivet::ToRivetSqliteExecRequest(v) => { + v4::ToRivet::ToRivetSqliteExecRequest(convert_to_rivet_sqlite_exec_request_v5_to_v4(v)?) + } + v5::ToRivet::ToRivetSqliteExecuteRequest(v) => v4::ToRivet::ToRivetSqliteExecuteRequest( + convert_to_rivet_sqlite_execute_request_v5_to_v4(v)?, + ), + }) +} + +pub fn convert_protocol_metadata_v5_to_v4(x: v5::ProtocolMetadata) -> Result { + Ok(v4::ProtocolMetadata { + envoy_lost_threshold: x.envoy_lost_threshold, + actor_stop_threshold: x.actor_stop_threshold, + max_response_payload_size: x.max_response_payload_size, + }) +} + +pub fn convert_to_envoy_init_v5_to_v4(x: v5::ToEnvoyInit) -> Result { + Ok(v4::ToEnvoyInit { + metadata: convert_protocol_metadata_v5_to_v4(x.metadata)?, + }) +} + +pub fn convert_to_envoy_commands_v5_to_v4(x: v5::ToEnvoyCommands) -> Result { + Ok(x.into_iter() + .map(|v| convert_command_wrapper_v5_to_v4(v)) + .collect::>>()?) +} + +pub fn convert_to_envoy_ack_events_v5_to_v4( + x: v5::ToEnvoyAckEvents, +) -> Result { + Ok(v4::ToEnvoyAckEvents { + last_event_checkpoints: x + .last_event_checkpoints + .into_iter() + .map(|v| convert_actor_checkpoint_v5_to_v4(v)) + .collect::>>()?, + }) +} + +pub fn convert_to_envoy_kv_response_v5_to_v4( + x: v5::ToEnvoyKvResponse, +) -> Result { + Ok(v4::ToEnvoyKvResponse { + request_id: x.request_id, + data: convert_kv_response_data_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_get_pages_response_v5_to_v4( + x: v5::ToEnvoySqliteGetPagesResponse, +) -> Result { + Ok(v4::ToEnvoySqliteGetPagesResponse { + request_id: x.request_id, + data: convert_sqlite_get_pages_response_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_commit_response_v5_to_v4( + x: v5::ToEnvoySqliteCommitResponse, +) -> Result { + Ok(v4::ToEnvoySqliteCommitResponse { + request_id: x.request_id, + data: convert_sqlite_commit_response_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_exec_response_v5_to_v4( + x: v5::ToEnvoySqliteExecResponse, +) -> Result { + Ok(v4::ToEnvoySqliteExecResponse { + request_id: x.request_id, + data: convert_sqlite_exec_response_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_envoy_sqlite_execute_response_v5_to_v4( + x: v5::ToEnvoySqliteExecuteResponse, +) -> Result { + Ok(v4::ToEnvoySqliteExecuteResponse { + request_id: x.request_id, + data: convert_sqlite_execute_response_v5_to_v4(x.data)?, + }) +} + +pub fn convert_to_envoy_v5_to_v4(x: v5::ToEnvoy) -> Result { + Ok(match x { + v5::ToEnvoy::ToEnvoyInit(v) => v4::ToEnvoy::ToEnvoyInit(convert_to_envoy_init_v5_to_v4(v)?), + v5::ToEnvoy::ToEnvoyCommands(v) => { + v4::ToEnvoy::ToEnvoyCommands(convert_to_envoy_commands_v5_to_v4(v)?) + } + v5::ToEnvoy::ToEnvoyAckEvents(v) => { + v4::ToEnvoy::ToEnvoyAckEvents(convert_to_envoy_ack_events_v5_to_v4(v)?) + } + v5::ToEnvoy::ToEnvoyKvResponse(v) => { + v4::ToEnvoy::ToEnvoyKvResponse(convert_to_envoy_kv_response_v5_to_v4(v)?) + } + v5::ToEnvoy::ToEnvoyTunnelMessage(v) => { + v4::ToEnvoy::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v5_to_v4(v)?) + } + v5::ToEnvoy::ToEnvoyPing(v) => v4::ToEnvoy::ToEnvoyPing(convert_to_envoy_ping_v5_to_v4(v)?), + v5::ToEnvoy::ToEnvoySqliteGetPagesResponse(v) => { + v4::ToEnvoy::ToEnvoySqliteGetPagesResponse( + convert_to_envoy_sqlite_get_pages_response_v5_to_v4(v)?, + ) + } + v5::ToEnvoy::ToEnvoySqliteCommitResponse(v) => v4::ToEnvoy::ToEnvoySqliteCommitResponse( + convert_to_envoy_sqlite_commit_response_v5_to_v4(v)?, + ), + v5::ToEnvoy::ToEnvoySqliteExecResponse(v) => v4::ToEnvoy::ToEnvoySqliteExecResponse( + convert_to_envoy_sqlite_exec_response_v5_to_v4(v)?, + ), + v5::ToEnvoy::ToEnvoySqliteExecuteResponse(v) => v4::ToEnvoy::ToEnvoySqliteExecuteResponse( + convert_to_envoy_sqlite_execute_response_v5_to_v4(v)?, + ), + }) +} + +pub fn convert_to_envoy_conn_ping_v5_to_v4(x: v5::ToEnvoyConnPing) -> Result { + Ok(v4::ToEnvoyConnPing { + gateway_id: x.gateway_id, + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_envoy_conn_v5_to_v4(x: v5::ToEnvoyConn) -> Result { + Ok(match x { + v5::ToEnvoyConn::ToEnvoyConnPing(v) => { + v4::ToEnvoyConn::ToEnvoyConnPing(convert_to_envoy_conn_ping_v5_to_v4(v)?) + } + v5::ToEnvoyConn::ToEnvoyConnClose => v4::ToEnvoyConn::ToEnvoyConnClose, + v5::ToEnvoyConn::ToEnvoyCommands(v) => { + v4::ToEnvoyConn::ToEnvoyCommands(convert_to_envoy_commands_v5_to_v4(v)?) + } + v5::ToEnvoyConn::ToEnvoyAckEvents(v) => { + v4::ToEnvoyConn::ToEnvoyAckEvents(convert_to_envoy_ack_events_v5_to_v4(v)?) + } + v5::ToEnvoyConn::ToEnvoyTunnelMessage(v) => { + v4::ToEnvoyConn::ToEnvoyTunnelMessage(convert_to_envoy_tunnel_message_v5_to_v4(v)?) + } + }) +} + +pub fn convert_to_gateway_pong_v5_to_v4(x: v5::ToGatewayPong) -> Result { + Ok(v4::ToGatewayPong { + request_id: x.request_id, + ts: x.ts, + }) +} + +pub fn convert_to_gateway_v5_to_v4(x: v5::ToGateway) -> Result { + Ok(match x { + v5::ToGateway::ToGatewayPong(v) => { + v4::ToGateway::ToGatewayPong(convert_to_gateway_pong_v5_to_v4(v)?) + } + v5::ToGateway::ToRivetTunnelMessage(v) => { + v4::ToGateway::ToRivetTunnelMessage(convert_to_rivet_tunnel_message_v5_to_v4(v)?) + } + }) +} + +pub fn convert_to_outbound_actor_start_v5_to_v4( + x: v5::ToOutboundActorStart, +) -> Result { + Ok(v4::ToOutboundActorStart { + namespace_id: x.namespace_id, + pool_name: x.pool_name, + checkpoint: convert_actor_checkpoint_v5_to_v4(x.checkpoint)?, + actor_config: convert_actor_config_v5_to_v4(x.actor_config)?, + }) +} + +pub fn convert_to_outbound_v5_to_v4(x: v5::ToOutbound) -> Result { + Ok(match x { + v5::ToOutbound::ToOutboundActorStart(v) => { + v4::ToOutbound::ToOutboundActorStart(convert_to_outbound_actor_start_v5_to_v4(v)?) + } + }) +} diff --git a/engine/sdks/rust/envoy-protocol/src/versioned_conversions.in b/engine/sdks/rust/envoy-protocol/src/versioned_conversions.in deleted file mode 100644 index 8a2cddf624..0000000000 --- a/engine/sdks/rust/envoy-protocol/src/versioned_conversions.in +++ /dev/null @@ -1,532 +0,0 @@ -macro_rules! impl_pair_conversions { - ( - $from:ident, $to:ident, - $stop_actor_reason:ident, - $stop_code:ident, - $actor_intent:ident, - $actor_state:ident, - $event:ident, - $event_wrapper:ident, - $to_envoy_ack_events:ident, - $to_rivet_ack_commands:ident, - $kv_list_query:ident, - $kv_request_data:ident, - $kv_response_data:ident, - $to_envoy_kv_response:ident, - $to_rivet_kv_request:ident, - $to_rivet_metadata:ident, - $message_id:ident, - $to_rivet_tunnel_message_kind:ident, - $to_rivet_tunnel_message:ident, - $to_envoy_tunnel_message_kind:ident, - $to_envoy_tunnel_message:ident - ) => { - #[allow(dead_code)] - fn $stop_actor_reason(reason: $from::StopActorReason) -> $to::StopActorReason { - match reason { - $from::StopActorReason::SleepIntent => $to::StopActorReason::SleepIntent, - $from::StopActorReason::StopIntent => $to::StopActorReason::StopIntent, - $from::StopActorReason::Destroy => $to::StopActorReason::Destroy, - $from::StopActorReason::GoingAway => $to::StopActorReason::GoingAway, - $from::StopActorReason::Lost => $to::StopActorReason::Lost, - } - } - - #[allow(dead_code)] - fn $stop_code(code: $from::StopCode) -> $to::StopCode { - match code { - $from::StopCode::Ok => $to::StopCode::Ok, - $from::StopCode::Error => $to::StopCode::Error, - } - } - - #[allow(dead_code)] - fn $actor_intent(intent: $from::ActorIntent) -> $to::ActorIntent { - match intent { - $from::ActorIntent::ActorIntentSleep => $to::ActorIntent::ActorIntentSleep, - $from::ActorIntent::ActorIntentStop => $to::ActorIntent::ActorIntentStop, - } - } - - #[allow(dead_code)] - fn $actor_state(state: $from::ActorState) -> $to::ActorState { - match state { - $from::ActorState::ActorStateRunning => $to::ActorState::ActorStateRunning, - $from::ActorState::ActorStateStopped(stopped) => { - $to::ActorState::ActorStateStopped($to::ActorStateStopped { - code: $stop_code(stopped.code), - message: stopped.message, - }) - } - } - } - - #[allow(dead_code)] - fn $event(event: $from::Event) -> $to::Event { - match event { - $from::Event::EventActorIntent(intent) => { - $to::Event::EventActorIntent($to::EventActorIntent { - intent: $actor_intent(intent.intent), - }) - } - $from::Event::EventActorStateUpdate(state) => { - $to::Event::EventActorStateUpdate($to::EventActorStateUpdate { - state: $actor_state(state.state), - }) - } - $from::Event::EventActorSetAlarm(alarm) => { - $to::Event::EventActorSetAlarm($to::EventActorSetAlarm { - alarm_ts: alarm.alarm_ts, - }) - } - } - } - - #[allow(dead_code)] - fn $event_wrapper(wrapper: $from::EventWrapper) -> $to::EventWrapper { - $to::EventWrapper { - checkpoint: $to::ActorCheckpoint { - actor_id: wrapper.checkpoint.actor_id, - generation: wrapper.checkpoint.generation, - index: wrapper.checkpoint.index, - }, - inner: $event(wrapper.inner), - } - } - - #[allow(dead_code)] - fn $to_envoy_ack_events(ack: $from::ToEnvoyAckEvents) -> $to::ToEnvoyAckEvents { - $to::ToEnvoyAckEvents { - last_event_checkpoints: ack - .last_event_checkpoints - .into_iter() - .map(|checkpoint| $to::ActorCheckpoint { - actor_id: checkpoint.actor_id, - generation: checkpoint.generation, - index: checkpoint.index, - }) - .collect(), - } - } - - #[allow(dead_code)] - fn $to_rivet_ack_commands(ack: $from::ToRivetAckCommands) -> $to::ToRivetAckCommands { - $to::ToRivetAckCommands { - last_command_checkpoints: ack - .last_command_checkpoints - .into_iter() - .map(|checkpoint| $to::ActorCheckpoint { - actor_id: checkpoint.actor_id, - generation: checkpoint.generation, - index: checkpoint.index, - }) - .collect(), - } - } - - #[allow(dead_code)] - fn $kv_list_query(query: $from::KvListQuery) -> $to::KvListQuery { - match query { - $from::KvListQuery::KvListAllQuery => $to::KvListQuery::KvListAllQuery, - $from::KvListQuery::KvListRangeQuery(range) => { - $to::KvListQuery::KvListRangeQuery($to::KvListRangeQuery { - start: range.start, - end: range.end, - exclusive: range.exclusive, - }) - } - $from::KvListQuery::KvListPrefixQuery(prefix) => { - $to::KvListQuery::KvListPrefixQuery($to::KvListPrefixQuery { key: prefix.key }) - } - } - } - - #[allow(dead_code)] - fn $kv_request_data(data: $from::KvRequestData) -> $to::KvRequestData { - match data { - $from::KvRequestData::KvGetRequest(request) => { - $to::KvRequestData::KvGetRequest($to::KvGetRequest { keys: request.keys }) - } - $from::KvRequestData::KvListRequest(request) => { - $to::KvRequestData::KvListRequest($to::KvListRequest { - query: $kv_list_query(request.query), - reverse: request.reverse, - limit: request.limit, - }) - } - $from::KvRequestData::KvPutRequest(request) => { - $to::KvRequestData::KvPutRequest($to::KvPutRequest { - keys: request.keys, - values: request.values, - }) - } - $from::KvRequestData::KvDeleteRequest(request) => { - $to::KvRequestData::KvDeleteRequest($to::KvDeleteRequest { - keys: request.keys, - }) - } - $from::KvRequestData::KvDeleteRangeRequest(request) => { - $to::KvRequestData::KvDeleteRangeRequest($to::KvDeleteRangeRequest { - start: request.start, - end: request.end, - }) - } - $from::KvRequestData::KvDropRequest => $to::KvRequestData::KvDropRequest, - } - } - - #[allow(dead_code)] - fn $kv_response_data(data: $from::KvResponseData) -> $to::KvResponseData { - match data { - $from::KvResponseData::KvErrorResponse(response) => { - $to::KvResponseData::KvErrorResponse($to::KvErrorResponse { - message: response.message, - }) - } - $from::KvResponseData::KvGetResponse(response) => { - $to::KvResponseData::KvGetResponse($to::KvGetResponse { - keys: response.keys, - values: response.values, - metadata: response - .metadata - .into_iter() - .map(|metadata| $to::KvMetadata { - version: metadata.version, - update_ts: metadata.update_ts, - }) - .collect(), - }) - } - $from::KvResponseData::KvListResponse(response) => { - $to::KvResponseData::KvListResponse($to::KvListResponse { - keys: response.keys, - values: response.values, - metadata: response - .metadata - .into_iter() - .map(|metadata| $to::KvMetadata { - version: metadata.version, - update_ts: metadata.update_ts, - }) - .collect(), - }) - } - $from::KvResponseData::KvPutResponse => $to::KvResponseData::KvPutResponse, - $from::KvResponseData::KvDeleteResponse => $to::KvResponseData::KvDeleteResponse, - $from::KvResponseData::KvDropResponse => $to::KvResponseData::KvDropResponse, - } - } - - #[allow(dead_code)] - fn $to_envoy_kv_response(response: $from::ToEnvoyKvResponse) -> $to::ToEnvoyKvResponse { - $to::ToEnvoyKvResponse { - request_id: response.request_id, - data: $kv_response_data(response.data), - } - } - - #[allow(dead_code)] - fn $to_rivet_kv_request(request: $from::ToRivetKvRequest) -> $to::ToRivetKvRequest { - $to::ToRivetKvRequest { - actor_id: request.actor_id, - request_id: request.request_id, - data: $kv_request_data(request.data), - } - } - - #[allow(dead_code)] - fn $to_rivet_metadata(metadata: $from::ToRivetMetadata) -> $to::ToRivetMetadata { - $to::ToRivetMetadata { - prepopulate_actor_names: metadata.prepopulate_actor_names.map(|actor_names| { - actor_names - .into_iter() - .map(|(name, actor_name)| { - ( - name, - $to::ActorName { - metadata: actor_name.metadata, - }, - ) - }) - .collect() - }), - metadata: metadata.metadata, - } - } - - #[allow(dead_code)] - fn $message_id(message_id: $from::MessageId) -> $to::MessageId { - $to::MessageId { - gateway_id: message_id.gateway_id, - request_id: message_id.request_id, - message_index: message_id.message_index, - } - } - - #[allow(dead_code)] - fn $to_rivet_tunnel_message_kind( - kind: $from::ToRivetTunnelMessageKind, - ) -> $to::ToRivetTunnelMessageKind { - match kind { - $from::ToRivetTunnelMessageKind::ToRivetResponseStart(start) => { - $to::ToRivetTunnelMessageKind::ToRivetResponseStart($to::ToRivetResponseStart { - status: start.status, - headers: start.headers, - body: start.body, - stream: start.stream, - }) - } - $from::ToRivetTunnelMessageKind::ToRivetResponseChunk(chunk) => { - $to::ToRivetTunnelMessageKind::ToRivetResponseChunk($to::ToRivetResponseChunk { - body: chunk.body, - finish: chunk.finish, - }) - } - $from::ToRivetTunnelMessageKind::ToRivetResponseAbort => { - $to::ToRivetTunnelMessageKind::ToRivetResponseAbort - } - $from::ToRivetTunnelMessageKind::ToRivetWebSocketOpen(open) => { - $to::ToRivetTunnelMessageKind::ToRivetWebSocketOpen($to::ToRivetWebSocketOpen { - can_hibernate: open.can_hibernate, - }) - } - $from::ToRivetTunnelMessageKind::ToRivetWebSocketMessage(message) => { - $to::ToRivetTunnelMessageKind::ToRivetWebSocketMessage( - $to::ToRivetWebSocketMessage { - data: message.data, - binary: message.binary, - }, - ) - } - $from::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck(ack) => { - $to::ToRivetTunnelMessageKind::ToRivetWebSocketMessageAck( - $to::ToRivetWebSocketMessageAck { index: ack.index }, - ) - } - $from::ToRivetTunnelMessageKind::ToRivetWebSocketClose(close) => { - $to::ToRivetTunnelMessageKind::ToRivetWebSocketClose( - $to::ToRivetWebSocketClose { - code: close.code, - reason: close.reason, - hibernate: close.hibernate, - }, - ) - } - } - } - - #[allow(dead_code)] - fn $to_rivet_tunnel_message( - message: $from::ToRivetTunnelMessage, - ) -> $to::ToRivetTunnelMessage { - $to::ToRivetTunnelMessage { - message_id: $message_id(message.message_id), - message_kind: $to_rivet_tunnel_message_kind(message.message_kind), - } - } - - #[allow(dead_code)] - fn $to_envoy_tunnel_message_kind( - kind: $from::ToEnvoyTunnelMessageKind, - ) -> $to::ToEnvoyTunnelMessageKind { - match kind { - $from::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart(start) => { - $to::ToEnvoyTunnelMessageKind::ToEnvoyRequestStart($to::ToEnvoyRequestStart { - actor_id: start.actor_id, - method: start.method, - path: start.path, - headers: start.headers, - body: start.body, - stream: start.stream, - }) - } - $from::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk(chunk) => { - $to::ToEnvoyTunnelMessageKind::ToEnvoyRequestChunk($to::ToEnvoyRequestChunk { - body: chunk.body, - finish: chunk.finish, - }) - } - $from::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort => { - $to::ToEnvoyTunnelMessageKind::ToEnvoyRequestAbort - } - $from::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen(open) => { - $to::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketOpen($to::ToEnvoyWebSocketOpen { - actor_id: open.actor_id, - path: open.path, - headers: open.headers, - }) - } - $from::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage(message) => { - $to::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketMessage( - $to::ToEnvoyWebSocketMessage { - data: message.data, - binary: message.binary, - }, - ) - } - $from::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose(close) => { - $to::ToEnvoyTunnelMessageKind::ToEnvoyWebSocketClose( - $to::ToEnvoyWebSocketClose { - code: close.code, - reason: close.reason, - }, - ) - } - } - } - - #[allow(dead_code)] - fn $to_envoy_tunnel_message( - message: $from::ToEnvoyTunnelMessage, - ) -> $to::ToEnvoyTunnelMessage { - $to::ToEnvoyTunnelMessage { - message_id: $message_id(message.message_id), - message_kind: $to_envoy_tunnel_message_kind(message.message_kind), - } - } - }; -} - -impl_pair_conversions!( - v1, - v2, - convert_stop_actor_reason_v1_to_v2, - convert_stop_code_v1_to_v2, - convert_actor_intent_v1_to_v2, - convert_actor_state_v1_to_v2, - convert_event_v1_to_v2, - convert_event_wrapper_v1_to_v2, - convert_to_envoy_ack_events_v1_to_v2, - convert_to_rivet_ack_commands_v1_to_v2, - convert_kv_list_query_v1_to_v2, - convert_kv_request_data_v1_to_v2, - convert_kv_response_data_v1_to_v2, - convert_to_envoy_kv_response_v1_to_v2, - convert_to_rivet_kv_request_v1_to_v2, - convert_to_rivet_metadata_v1_to_v2, - convert_message_id_v1_to_v2, - convert_to_rivet_tunnel_message_kind_v1_to_v2, - convert_to_rivet_tunnel_message_v1_to_v2, - convert_to_envoy_tunnel_message_kind_v1_to_v2, - convert_to_envoy_tunnel_message_v1_to_v2 -); - -impl_pair_conversions!( - v2, - v1, - convert_stop_actor_reason_v2_to_v1, - convert_stop_code_v2_to_v1, - convert_actor_intent_v2_to_v1, - convert_actor_state_v2_to_v1, - convert_event_v2_to_v1, - convert_event_wrapper_v2_to_v1, - convert_to_envoy_ack_events_v2_to_v1, - convert_to_rivet_ack_commands_v2_to_v1, - convert_kv_list_query_v2_to_v1, - convert_kv_request_data_v2_to_v1, - convert_kv_response_data_v2_to_v1, - convert_to_envoy_kv_response_v2_to_v1, - convert_to_rivet_kv_request_v2_to_v1, - convert_to_rivet_metadata_v2_to_v1, - convert_message_id_v2_to_v1, - convert_to_rivet_tunnel_message_kind_v2_to_v1, - convert_to_rivet_tunnel_message_v2_to_v1, - convert_to_envoy_tunnel_message_kind_v2_to_v1, - convert_to_envoy_tunnel_message_v2_to_v1 -); - -impl_pair_conversions!( - v1, - v3, - convert_stop_actor_reason_v1_to_v3, - convert_stop_code_v1_to_v3, - convert_actor_intent_v1_to_v3, - convert_actor_state_v1_to_v3, - convert_event_v1_to_v3, - convert_event_wrapper_v1_to_v3, - convert_to_envoy_ack_events_v1_to_v3, - convert_to_rivet_ack_commands_v1_to_v3, - convert_kv_list_query_v1_to_v3, - convert_kv_request_data_v1_to_v3, - convert_kv_response_data_v1_to_v3, - convert_to_envoy_kv_response_v1_to_v3, - convert_to_rivet_kv_request_v1_to_v3, - convert_to_rivet_metadata_v1_to_v3, - convert_message_id_v1_to_v3, - convert_to_rivet_tunnel_message_kind_v1_to_v3, - convert_to_rivet_tunnel_message_v1_to_v3, - convert_to_envoy_tunnel_message_kind_v1_to_v3, - convert_to_envoy_tunnel_message_v1_to_v3 -); - -impl_pair_conversions!( - v2, - v3, - convert_stop_actor_reason_v2_to_v3, - convert_stop_code_v2_to_v3, - convert_actor_intent_v2_to_v3, - convert_actor_state_v2_to_v3, - convert_event_v2_to_v3, - convert_event_wrapper_v2_to_v3, - convert_to_envoy_ack_events_v2_to_v3, - convert_to_rivet_ack_commands_v2_to_v3, - convert_kv_list_query_v2_to_v3, - convert_kv_request_data_v2_to_v3, - convert_kv_response_data_v2_to_v3, - convert_to_envoy_kv_response_v2_to_v3, - convert_to_rivet_kv_request_v2_to_v3, - convert_to_rivet_metadata_v2_to_v3, - convert_message_id_v2_to_v3, - convert_to_rivet_tunnel_message_kind_v2_to_v3, - convert_to_rivet_tunnel_message_v2_to_v3, - convert_to_envoy_tunnel_message_kind_v2_to_v3, - convert_to_envoy_tunnel_message_v2_to_v3 -); - -impl_pair_conversions!( - v3, - v1, - convert_stop_actor_reason_v3_to_v1, - convert_stop_code_v3_to_v1, - convert_actor_intent_v3_to_v1, - convert_actor_state_v3_to_v1, - convert_event_v3_to_v1, - convert_event_wrapper_v3_to_v1, - convert_to_envoy_ack_events_v3_to_v1, - convert_to_rivet_ack_commands_v3_to_v1, - convert_kv_list_query_v3_to_v1, - convert_kv_request_data_v3_to_v1, - convert_kv_response_data_v3_to_v1, - convert_to_envoy_kv_response_v3_to_v1, - convert_to_rivet_kv_request_v3_to_v1, - convert_to_rivet_metadata_v3_to_v1, - convert_message_id_v3_to_v1, - convert_to_rivet_tunnel_message_kind_v3_to_v1, - convert_to_rivet_tunnel_message_v3_to_v1, - convert_to_envoy_tunnel_message_kind_v3_to_v1, - convert_to_envoy_tunnel_message_v3_to_v1 -); - -impl_pair_conversions!( - v3, - v2, - convert_stop_actor_reason_v3_to_v2, - convert_stop_code_v3_to_v2, - convert_actor_intent_v3_to_v2, - convert_actor_state_v3_to_v2, - convert_event_v3_to_v2, - convert_event_wrapper_v3_to_v2, - convert_to_envoy_ack_events_v3_to_v2, - convert_to_rivet_ack_commands_v3_to_v2, - convert_kv_list_query_v3_to_v2, - convert_kv_request_data_v3_to_v2, - convert_kv_response_data_v3_to_v2, - convert_to_envoy_kv_response_v3_to_v2, - convert_to_rivet_kv_request_v3_to_v2, - convert_to_rivet_metadata_v3_to_v2, - convert_message_id_v3_to_v2, - convert_to_rivet_tunnel_message_kind_v3_to_v2, - convert_to_rivet_tunnel_message_v3_to_v2, - convert_to_envoy_tunnel_message_kind_v3_to_v2, - convert_to_envoy_tunnel_message_v3_to_v2 -); diff --git a/engine/sdks/rust/envoy-protocol/tests/remote_sql_compat.rs b/engine/sdks/rust/envoy-protocol/tests/remote_sql_compat.rs index 185619d6b8..2fca661df7 100644 --- a/engine/sdks/rust/envoy-protocol/tests/remote_sql_compat.rs +++ b/engine/sdks/rust/envoy-protocol/tests/remote_sql_compat.rs @@ -153,13 +153,16 @@ fn v4_remote_sql_payloads_do_not_decode_as_v3() -> Result<()> { #[test] fn all_remote_sql_request_variants_require_v4() { + // The remote SQL feature drops at the v4 -> v3 boundary, so the chain + // reports target_version = 3 regardless of how much further down we are + // asking serialize() to walk. for version in 1..4 { for request in [remote_sql_request_exec(), remote_sql_request_execute()] { let err = ToRivet::wrap_latest(request) .serialize(version) .expect_err("remote SQL request variant must not serialize below v4"); - assert_compatibility_error(err, ProtocolCompatibilityDirection::ToRivet, version); + assert_compatibility_error(err, ProtocolCompatibilityDirection::ToRivet, 3); } } } @@ -172,7 +175,7 @@ fn all_remote_sql_response_variants_require_v4() { .serialize(version) .expect_err("remote SQL response variant must not serialize below v4"); - assert_compatibility_error(err, ProtocolCompatibilityDirection::ToEnvoy, version); + assert_compatibility_error(err, ProtocolCompatibilityDirection::ToEnvoy, 3); } } } diff --git a/package.json b/package.json index 5afce83c21..590341f7d4 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "@babel/runtime": "^7.29.2", "@iarna/toml": "^2.2.5", "@sentry/vite-plugin": "^2.23.1", - "fast-glob": "^3.3.3" + "fast-glob": "^3.3.3", + "handlebars": "^4.7.9" }, "resolutions": { "rivetkit": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b28832b57..ebafd5a634 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,6 +45,9 @@ importers: fast-glob: specifier: ^3.3.3 version: 3.3.3 + handlebars: + specifier: ^4.7.9 + version: 4.7.9 devDependencies: '@bare-ts/tools': specifier: 0.15.0 @@ -2044,7 +2047,7 @@ importers: version: 5.2.2(react-hook-form@7.62.0(react@19.1.0)) '@ladle/react': specifier: ^5.1.1 - version: 5.1.1(@swc/helpers@0.5.17)(@types/node@20.19.13)(@types/react@19.2.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + version: 5.1.1(@swc/helpers@0.5.17)(@types/node@20.19.13)(@types/react@19.2.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) '@marsidev/react-turnstile': specifier: ^1.5.0 version: 1.5.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -2293,7 +2296,7 @@ importers: version: 2.4.3 better-auth: specifier: ^1.5.6 - version: 1.5.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))(next@16.1.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 1.5.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))(next@16.1.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) canvas-confetti: specifier: ^1.9.3 version: 1.9.3 @@ -2413,7 +2416,7 @@ importers: version: 5.2.0(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.17))(@types/node@20.19.13)(typescript@5.9.3))(typescript@5.9.3) unplugin-macros: specifier: ^0.18.3 - version: 0.18.3(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 0.18.3(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) usehooks-ts: specifier: ^3.1.1 version: 3.1.1(react@19.1.0) @@ -2435,7 +2438,7 @@ importers: version: 2.14.4(@types/node@20.19.13)(typescript@5.9.3) vitest: specifier: ^4.0.18 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) frontend/packages/components: dependencies: @@ -12101,6 +12104,11 @@ packages: hachure-fill@0.5.2: resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} + engines: {node: '>=0.4.7'} + hasBin: true + has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -16060,6 +16068,11 @@ packages: ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + uint8array-extras@1.5.0: resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} engines: {node: '>=18'} @@ -16814,6 +16827,13 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -20024,7 +20044,7 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - '@ladle/react@5.1.1(@swc/helpers@0.5.17)(@types/node@20.19.13)(@types/react@19.2.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)': + '@ladle/react@5.1.1(@swc/helpers@0.5.17)(@types/node@20.19.13)(@types/react@19.2.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)': dependencies: '@babel/code-frame': 7.29.0 '@babel/core': 7.29.0 @@ -20036,8 +20056,8 @@ snapshots: '@ladle/react-context': 1.0.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@mdx-js/mdx': 3.1.1 '@mdx-js/react': 3.1.1(@types/react@19.2.13)(react@19.1.0) - '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) - '@vitejs/plugin-react-swc': 3.11.0(@swc/helpers@0.5.17)(vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-react-swc': 3.11.0(@swc/helpers@0.5.17)(vite@6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) axe-core: 4.11.1 boxen: 8.0.1 chokidar: 4.0.3 @@ -20064,8 +20084,8 @@ snapshots: remark-gfm: 4.0.1 source-map: 0.7.6 vfile: 6.0.3 - vite: 6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vite-tsconfig-paths: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vite: 6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-tsconfig-paths: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) transitivePeerDependencies: - '@swc/helpers' - '@types/node' @@ -24144,11 +24164,11 @@ snapshots: d3-time-format: 4.1.0 internmap: 2.0.3 - '@vitejs/plugin-react-swc@3.11.0(@swc/helpers@0.5.17)(vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react-swc@3.11.0(@swc/helpers@0.5.17)(vite@6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.27 '@swc/core': 1.15.11(@swc/helpers@0.5.17) - vite: 6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@swc/helpers' @@ -24188,7 +24208,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -24196,7 +24216,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -24290,14 +24310,14 @@ snapshots: msw: 2.14.4(@types/node@22.19.15)(typescript@5.9.3) vite: 5.4.21(@types/node@22.19.15)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) - '@vitest/mocker@4.0.18(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(vite@6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - msw: 2.14.4(@types/node@20.19.13)(typescript@5.9.3) - vite: 6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + msw: 2.12.10(@types/node@20.19.13)(typescript@5.9.3) + vite: 6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@2.1.9': dependencies: @@ -25112,7 +25132,7 @@ snapshots: bcryptjs@2.4.3: {} - better-auth@1.5.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))(next@16.1.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + better-auth@1.5.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))(next@16.1.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) '@better-auth/drizzle-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)) @@ -25139,7 +25159,7 @@ snapshots: pg: 8.17.2 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@cloudflare/workers-types' - '@opentelemetry/api' @@ -27525,6 +27545,15 @@ snapshots: hachure-fill@0.5.2: {} + handlebars@4.7.9: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + has-flag@3.0.0: {} has-flag@4.0.0: {} @@ -29764,8 +29793,7 @@ snapshots: negotiator@1.0.0: {} - neo-async@2.6.2: - optional: true + neo-async@2.6.2: {} neotraverse@0.6.18: {} @@ -32590,6 +32618,9 @@ snapshots: ufo@1.6.1: {} + uglify-js@3.19.3: + optional: true + uint8array-extras@1.5.0: {} ultrahtml@1.6.0: {} @@ -32714,13 +32745,13 @@ snapshots: unpipe@1.0.0: {} - unplugin-macros@0.18.3(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + unplugin-macros@0.18.3(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: ast-kit: 2.2.0 magic-string-ast: 1.0.3 unplugin: 2.3.10 - vite: 7.3.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vite-node: 5.2.0(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-node: 5.2.0(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -33007,13 +33038,13 @@ snapshots: - supports-color - terser - vite-node@5.2.0(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite-node@5.2.0(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: cac: 6.7.14 es-module-lexer: 1.7.0 obug: 2.0.0(ms@2.1.3) pathe: 2.0.3 - vite: 7.3.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -33086,13 +33117,13 @@ snapshots: - supports-color - typescript - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - typescript @@ -33150,7 +33181,7 @@ snapshots: stylus: 0.62.0 terser: 5.46.0 - vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -33161,7 +33192,7 @@ snapshots: optionalDependencies: '@types/node': 20.19.13 fsevents: 2.3.3 - jiti: 1.21.7 + jiti: 2.6.1 less: 4.4.1 lightningcss: 1.32.0 sass: 1.93.2 @@ -33210,7 +33241,7 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vite@7.3.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -33221,7 +33252,7 @@ snapshots: optionalDependencies: '@types/node': 20.19.13 fsevents: 2.3.3 - jiti: 1.21.7 + jiti: 2.6.1 less: 4.4.1 lightningcss: 1.32.0 sass: 1.93.2 @@ -33495,10 +33526,10 @@ snapshots: - supports-color - terser - vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(vite@6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -33515,7 +33546,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.13)(jiti@2.6.1)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 @@ -33699,6 +33730,14 @@ snapshots: word-wrap@1.2.5: {} + wordwrap@1.0.0: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 diff --git a/scripts/vbare-gen-converters/index.ts b/scripts/vbare-gen-converters/index.ts new file mode 100644 index 0000000000..e0ad1c0996 --- /dev/null +++ b/scripts/vbare-gen-converters/index.ts @@ -0,0 +1,560 @@ +#!/usr/bin/env tsx +/** + * Generate Rust boilerplate converters between two adjacent BARE schema versions. + * + * Each generated function maps every field/variant the two schemas have in + * common. Anything that exists on only one side becomes `todo!()` so the human + * implementing the migration is forced to make a decision. + * + * tsx index.ts \ + * [--types Type1,Type2] [--from-ns v3] [--to-ns v4] + * + * Two files are written: _to_.rs and _to_.rs. + * + * If --types is omitted, every type that exists in both schemas gets a + * converter. If --types is provided, only those types and the types they + * reference (transitively) are emitted. + * + * Types that resolve to a primitive (e.g. `type Id str`) are not given + * converters since `vN::Id` and `vM::Id` are the same Rust type and identity + * is a no-op. + */ +import { Command } from "commander"; +import { + Config, + parse, + type StructField, + type SymbolTable, + type Type, + resolveAlias, + symbols, + withoutExtra, +} from "@bare-ts/tools"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import Handlebars from "handlebars"; + +type SchemaMap = Map; +type Schema = { table: SymbolTable; map: SchemaMap }; + +const TEMPLATES_DIR = path.join(import.meta.dirname ?? path.dirname(new URL(import.meta.url).pathname), "templates"); + +function loadTemplate(name: string): Handlebars.TemplateDelegate { + const src = fs.readFileSync(path.join(TEMPLATES_DIR, `${name}.hbs`), "utf8"); + return Handlebars.compile(src, { noEscape: true }); +} + +const TEMPLATES = { + file: loadTemplate("file"), + struct: loadTemplate("struct"), + union: loadTemplate("union"), + enum: loadTemplate("enum"), + wrapperAlias: loadTemplate("wrapper-alias"), + todo: loadTemplate("todo"), +}; + +function loadSchema(p: string): Schema { + const ast = parse(fs.readFileSync(p, "utf8"), Config({ schema: p })); + const table = symbols(ast); + const map: SchemaMap = new Map(); + for (const def of ast.defs) map.set(def.alias, def.type); + return { table, map }; +} + +const RUST_KEYWORDS = new Set([ + "as", "break", "const", "continue", "crate", "else", "enum", "extern", "false", + "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", + "pub", "ref", "return", "self", "Self", "static", "struct", "super", "trait", + "true", "type", "unsafe", "use", "where", "while", "async", "await", "dyn", +]); + +function snake(s: string): string { + const out = s + .replace(/([a-z0-9])([A-Z])/g, "$1_$2") + .replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2") + .replace(/-/g, "_") + .toLowerCase(); + return RUST_KEYWORDS.has(out) ? `${out}_` : out; +} + +function pascalFromScreaming(s: string): string { + return s + .split("_") + .map((w) => (w.length === 0 ? "" : w[0].toUpperCase() + w.slice(1).toLowerCase())) + .join(""); +} + +function fnName(typeName: string, fromNs: string, toNs: string): string { + return `convert_${snake(typeName)}_${fromNs}_to_${toNs}`; +} + +function isVoidNamed(name: string, schema: Schema): boolean { + const t = schema.map.get(name); + return !!t && t.tag === "void"; +} + +function typesEqual(a: Type, b: Type): boolean { + return JSON.stringify(withoutExtra(a)) === JSON.stringify(withoutExtra(b)); +} + +// A type is "trivial" if its Rust representation requires no conversion across +// the two namespaces: primitives, data, void, and aggregates whose every leaf +// resolves to those. Aliases are followed. +function isTrivial(t: Type, schema: Schema): boolean { + switch (t.tag) { + case "alias": + return isTrivial(resolveAlias(t, schema.table), schema); + case "void": + case "data": + return true; + case "optional": + return isTrivial(t.types![0]!, schema); + case "list": + return isTrivial(t.types![0]!, schema); + case "map": + return isTrivial(t.types![0]!, schema) && isTrivial(t.types![1]!, schema); + case "struct": + case "union": + case "enum": + return false; + default: + // All BaseTypes (u8/i32/.../bool/str). + return true; + } +} + +// Whether the user-defined type `name` needs a converter function emitted. +// Skipped if both schemas resolve it to a trivial Rust type (e.g. `type Id str`). +function needsConverter(name: string, from: Schema, to: Schema): boolean { + const f = from.map.get(name); + const t = to.map.get(name); + if (!f || !t) return false; + if (f.tag === "void" || t.tag === "void") return false; + if (isTrivial(f, from) && isTrivial(t, to)) return false; + return true; +} + +function transitiveSharedTypes(seed: string[], from: Schema, to: Schema): Set { + const shared = new Set(); + for (const name of from.map.keys()) if (to.map.has(name)) shared.add(name); + + const out = new Set(); + const stack: string[] = []; + for (const s of seed) { + if (!shared.has(s)) { + console.warn(`warn: --types entry '${s}' is not present in both schemas; skipping`); + continue; + } + stack.push(s); + } + + while (stack.length > 0) { + const name = stack.pop()!; + if (out.has(name)) continue; + out.add(name); + + const visit = (t: Type) => { + if (t.tag === "alias") { + if (shared.has(t.data) && !out.has(t.data)) stack.push(t.data); + return; + } + if (t.types) for (const sub of t.types) visit(sub); + }; + const fromType = from.map.get(name); + const toType = to.map.get(name); + if (fromType) visit(fromType); + if (toType) visit(toType); + } + return out; +} + +// Render an expression converting `expr` (typed as `t` in fromNs) into the +// target shape in toNs. `emitted` is the set of named types with a converter +// function emitted; references outside that set inline as identity when the +// alias resolves to a trivial type in both schemas, otherwise `todo!()`. +// +// Converter functions return `Result`, so this returns an expression of +// type `Result` when fallible (use the result with `?`) and a plain +// expression when no nested converter is involved. +// +// Returns { expr, fallible }. `fallible` indicates whether the caller must +// propagate with `?` or wrap in `Ok(...)`. +function convertExpr( + t: Type, + expr: string, + fromNs: string, + toNs: string, + from: Schema, + to: Schema, + emitted: Set, +): { expr: string; fallible: boolean } { + switch (t.tag) { + case "void": + return { expr: "()", fallible: false }; + case "alias": { + if (emitted.has(t.data)) { + return { + expr: `${fnName(t.data, fromNs, toNs)}(${expr})?`, + fallible: true, + }; + } + const fromBody = from.map.get(t.data); + const toBody = to.map.get(t.data); + if (fromBody && toBody && isTrivial(fromBody, from) && isTrivial(toBody, to)) + return { expr, fallible: false }; + return { expr: "todo!()", fallible: false }; + } + case "optional": { + const inner = convertExpr( + t.types![0]!, + "v", + fromNs, + toNs, + from, + to, + emitted, + ); + if (inner.expr === "v") return { expr, fallible: false }; + if (inner.fallible) { + const innerNoQ = inner.expr.endsWith("?") + ? inner.expr.slice(0, -1) + : inner.expr; + return { + expr: `${expr}.map(|v| ${innerNoQ}).transpose()?`, + fallible: true, + }; + } + return { expr: `${expr}.map(|v| ${inner.expr})`, fallible: false }; + } + case "list": { + const inner = convertExpr( + t.types![0]!, + "v", + fromNs, + toNs, + from, + to, + emitted, + ); + if (inner.expr === "v") return { expr, fallible: false }; + if (inner.fallible) { + const innerNoQ = inner.expr.endsWith("?") + ? inner.expr.slice(0, -1) + : inner.expr; + return { + expr: `${expr}.into_iter().map(|v| ${innerNoQ}).collect::>>()?`, + fallible: true, + }; + } + return { + expr: `${expr}.into_iter().map(|v| ${inner.expr}).collect()`, + fallible: false, + }; + } + case "map": { + const k = convertExpr( + t.types![0]!, + "k", + fromNs, + toNs, + from, + to, + emitted, + ); + const v = convertExpr( + t.types![1]!, + "v", + fromNs, + toNs, + from, + to, + emitted, + ); + if (k.expr === "k" && v.expr === "v") + return { expr, fallible: false }; + const fallible = k.fallible || v.fallible; + if (fallible) { + return { + expr: `${expr}.into_iter().map(|(k, v)| -> Result<_> { Ok((${k.expr}, ${v.expr})) }).collect::>()?`, + fallible: true, + }; + } + return { + expr: `${expr}.into_iter().map(|(k, v)| (${k.expr}, ${v.expr})).collect()`, + fallible: false, + }; + } + default: + return { expr, fallible: false }; + } +} + +interface Ctx { + fromNs: string; + toNs: string; + from: Schema; + to: Schema; + emitted: Set; +} + +function renderStruct( + name: string, + fromBody: Extract, + toBody: Extract, + ctx: Ctx, +): string { + const fromMap = new Map(); + fromBody.data.forEach((f, i) => + fromMap.set(f.name, { field: f, type: fromBody.types![i]! }), + ); + const fields = toBody.data.map((f, i) => { + const toType = toBody.types![i]!; + const rustField = snake(f.name); + const fromEntry = fromMap.get(f.name); + if (!fromEntry || !typesEqual(fromEntry.type, toType)) { + return { name: rustField, expr: "todo!()" }; + } + return { + name: rustField, + expr: convertExpr( + fromEntry.type, + `x.${rustField}`, + ctx.fromNs, + ctx.toNs, + ctx.from, + ctx.to, + ctx.emitted, + ).expr, + }; + }); + return TEMPLATES.struct({ + fnName: fnName(name, ctx.fromNs, ctx.toNs), + name, + fromNs: ctx.fromNs, + toNs: ctx.toNs, + fields, + }); +} + +function renderUnion( + name: string, + fromBody: Extract, + toBody: Extract, + ctx: Ctx, +): string { + const toVariantSet = new Set(); + for (const t of toBody.types!) if (t.tag === "alias") toVariantSet.add(t.data); + + const arms: string[] = []; + for (const variant of fromBody.types!) { + if (variant.tag !== "alias") { + arms.push(`// inline union variant unsupported`); + continue; + } + const v = variant.data; + const fromVoid = isVoidNamed(v, ctx.from); + const toVoid = isVoidNamed(v, ctx.to); + + if (!toVariantSet.has(v)) { + arms.push( + `${ctx.fromNs}::${name}::${v}${fromVoid ? "" : "(_)"} => todo!(),`, + ); + continue; + } + if (fromVoid && toVoid) { + arms.push( + `${ctx.fromNs}::${name}::${v} => ${ctx.toNs}::${name}::${v},`, + ); + } else if (!fromVoid && !toVoid) { + const inner = ctx.emitted.has(v) + ? `${fnName(v, ctx.fromNs, ctx.toNs)}(v)?` + : (() => { + const fromBody2 = ctx.from.map.get(v); + const toBody2 = ctx.to.map.get(v); + if ( + fromBody2 && + toBody2 && + isTrivial(fromBody2, ctx.from) && + isTrivial(toBody2, ctx.to) + ) { + return "v"; + } + return null; + })(); + if (inner === null) { + arms.push(`${ctx.fromNs}::${name}::${v}(_) => todo!(),`); + } else { + arms.push( + `${ctx.fromNs}::${name}::${v}(v) => ${ctx.toNs}::${name}::${v}(${inner}),`, + ); + } + } else { + arms.push( + `${ctx.fromNs}::${name}::${v}${fromVoid ? "" : "(_)"} => todo!(),`, + ); + } + } + return TEMPLATES.union({ + fnName: fnName(name, ctx.fromNs, ctx.toNs), + name, + fromNs: ctx.fromNs, + toNs: ctx.toNs, + arms, + }); +} + +function renderEnum( + name: string, + fromBody: Extract, + toBody: Extract, + ctx: Ctx, +): string { + const toValues = new Set(toBody.data.map((v) => v.name)); + const arms = fromBody.data.map((v) => { + // @bare-ts/tools already gives the Rust-style PascalCase variant name. + const variant = v.name; + if (toValues.has(v.name)) + return `${ctx.fromNs}::${name}::${variant} => ${ctx.toNs}::${name}::${variant},`; + return `${ctx.fromNs}::${name}::${variant} => todo!(),`; + }); + return TEMPLATES.enum({ + fnName: fnName(name, ctx.fromNs, ctx.toNs), + name, + fromNs: ctx.fromNs, + toNs: ctx.toNs, + arms, + }); +} + +function renderConverter( + name: string, + fromBody: Type, + toBody: Type, + ctx: Ctx, +): string { + const renderTodo = () => + TEMPLATES.todo({ + fnName: fnName(name, ctx.fromNs, ctx.toNs), + name, + fromNs: ctx.fromNs, + toNs: ctx.toNs, + }); + + if (fromBody.tag !== toBody.tag) return renderTodo(); + if (fromBody.tag === "struct" && toBody.tag === "struct") + return renderStruct(name, fromBody, toBody, ctx); + if (fromBody.tag === "union" && toBody.tag === "union") + return renderUnion(name, fromBody, toBody, ctx); + if (fromBody.tag === "enum" && toBody.tag === "enum") + return renderEnum(name, fromBody, toBody, ctx); + + // Wrapper alias body (list/optional/map of a non-trivial inner type). + if (!typesEqual(fromBody, toBody)) return renderTodo(); + const e = convertExpr(fromBody, "x", ctx.fromNs, ctx.toNs, ctx.from, ctx.to, ctx.emitted); + return TEMPLATES.wrapperAlias({ + fnName: fnName(name, ctx.fromNs, ctx.toNs), + name, + fromNs: ctx.fromNs, + toNs: ctx.toNs, + expr: e.expr, + }); +} + +function emitFile( + fromNs: string, + toNs: string, + from: Schema, + to: Schema, + emitted: Set, + fromFile: string, + toFile: string, +): string { + const ctx: Ctx = { fromNs, toNs, from, to, emitted }; + + const order: string[] = []; + for (const name of to.map.keys()) { + if (emitted.has(name) && from.map.has(name)) order.push(name); + } + for (const name of emitted) { + if (!order.includes(name) && from.map.has(name) && to.map.has(name)) { + order.push(name); + } + } + + const converters = order.map((name) => ({ + body: renderConverter(name, from.map.get(name)!, to.map.get(name)!, ctx).trimEnd(), + })); + + return TEMPLATES.file({ fromNs, toNs, fromFile, toFile, converters }); +} + +function main() { + const program = new Command() + .argument("", "path to old .bare schema") + .argument("", "path to new .bare schema") + .argument("", "directory where the two .rs files are written") + .option("--types ", "comma-separated root types to emit (default: all shared non-trivial types)") + .option("--from-ns ", "from-side Rust module name (default: from filename basename)") + .option("--to-ns ", "to-side Rust module name (default: to filename basename)") + .parse(process.argv); + + const [fromPath, toPath, outDir] = program.processedArgs as [string, string, string]; + const opts = program.opts<{ types?: string; fromNs?: string; toNs?: string }>(); + const fromNs = opts.fromNs ?? path.basename(fromPath, ".bare"); + const toNs = opts.toNs ?? path.basename(toPath, ".bare"); + + const from = loadSchema(fromPath); + const to = loadSchema(toPath); + + let candidates: Set; + if (opts.types) { + const seeds = opts.types.split(",").map((s) => s.trim()).filter(Boolean); + candidates = transitiveSharedTypes(seeds, from, to); + } else { + candidates = new Set(); + for (const name of from.map.keys()) if (to.map.has(name)) candidates.add(name); + } + + const emitted = new Set(); + for (const name of candidates) { + if (needsConverter(name, from, to)) emitted.add(name); + } + + fs.mkdirSync(outDir, { recursive: true }); + + const forwardPath = path.join(outDir, `${fromNs}_to_${toNs}.rs`); + const backwardPath = path.join(outDir, `${toNs}_to_${fromNs}.rs`); + fs.writeFileSync( + forwardPath, + emitFile( + fromNs, + toNs, + from, + to, + emitted, + path.basename(fromPath), + path.basename(toPath), + ), + ); + fs.writeFileSync( + backwardPath, + emitFile( + toNs, + fromNs, + to, + from, + emitted, + path.basename(toPath), + path.basename(fromPath), + ), + ); + console.error(`wrote ${forwardPath}`); + console.error(`wrote ${backwardPath}`); + console.error(`emitted ${emitted.size} type converters in each direction`); + const skipped = candidates.size - emitted.size; + if (skipped > 0) { + console.error(`skipped ${skipped} trivial/void types (no converter needed)`); + } +} + +main(); diff --git a/scripts/vbare-gen-converters/templates/enum.hbs b/scripts/vbare-gen-converters/templates/enum.hbs new file mode 100644 index 0000000000..d5651ce316 --- /dev/null +++ b/scripts/vbare-gen-converters/templates/enum.hbs @@ -0,0 +1,7 @@ +pub fn {{fnName}}(x: {{fromNs}}::{{name}}) -> Result<{{toNs}}::{{name}}> { + Ok(match x { +{{#each arms}} + {{{this}}} +{{/each}} + }) +} diff --git a/scripts/vbare-gen-converters/templates/file.hbs b/scripts/vbare-gen-converters/templates/file.hbs new file mode 100644 index 0000000000..2cbbbf2e4c --- /dev/null +++ b/scripts/vbare-gen-converters/templates/file.hbs @@ -0,0 +1,14 @@ +// @generated initial scaffold by scripts/vbare-gen-converters +// from: {{fromFile}}, to: {{toFile}} +// Replace each todo!() with the migration semantics, then drop the @generated marker. + +#![allow(dead_code, unused_variables)] + +use anyhow::Result; + +use crate::generated::{ {{~fromNs}}, {{toNs~}} }; + +{{#each converters}} +{{{this.body}}} + +{{/each}} diff --git a/scripts/vbare-gen-converters/templates/struct.hbs b/scripts/vbare-gen-converters/templates/struct.hbs new file mode 100644 index 0000000000..f43a23ed49 --- /dev/null +++ b/scripts/vbare-gen-converters/templates/struct.hbs @@ -0,0 +1,7 @@ +pub fn {{fnName}}(x: {{fromNs}}::{{name}}) -> Result<{{toNs}}::{{name}}> { + Ok({{toNs}}::{{name}} { +{{#each fields}} + {{this.name}}: {{{this.expr}}}, +{{/each}} + }) +} diff --git a/scripts/vbare-gen-converters/templates/todo.hbs b/scripts/vbare-gen-converters/templates/todo.hbs new file mode 100644 index 0000000000..9378aecd0a --- /dev/null +++ b/scripts/vbare-gen-converters/templates/todo.hbs @@ -0,0 +1,4 @@ +pub fn {{fnName}}(x: {{fromNs}}::{{name}}) -> Result<{{toNs}}::{{name}}> { + let _ = x; + todo!() +} diff --git a/scripts/vbare-gen-converters/templates/union.hbs b/scripts/vbare-gen-converters/templates/union.hbs new file mode 100644 index 0000000000..d5651ce316 --- /dev/null +++ b/scripts/vbare-gen-converters/templates/union.hbs @@ -0,0 +1,7 @@ +pub fn {{fnName}}(x: {{fromNs}}::{{name}}) -> Result<{{toNs}}::{{name}}> { + Ok(match x { +{{#each arms}} + {{{this}}} +{{/each}} + }) +} diff --git a/scripts/vbare-gen-converters/templates/wrapper-alias.hbs b/scripts/vbare-gen-converters/templates/wrapper-alias.hbs new file mode 100644 index 0000000000..2a102b2b81 --- /dev/null +++ b/scripts/vbare-gen-converters/templates/wrapper-alias.hbs @@ -0,0 +1,3 @@ +pub fn {{fnName}}(x: {{fromNs}}::{{name}}) -> Result<{{toNs}}::{{name}}> { + Ok({{{expr}}}) +}