//! Optional sparse delivery of a completely recomputed pane surface.
use base64::{engine::general_purpose::STANDARD_NO_PAD, Engine as _};
use serde::{Deserialize, Serialize};
use super::{CellData, PaneSurfaceFrame, PaneSurfacePatchRow, ServerMessage};
mod decode;
pub(crate) const CAPABILITY: &str = "surface_delta";
pub(crate) const MESSAGE_KIND: &str = "endpoint.surface-delta.v1";
pub(crate) const MAX_SPANS: usize = 4096;
// This binary layout is frozen with MESSAGE_KIND, independently of the v1 core.
#[derive(Serialize, Deserialize)]
pub(crate) struct SurfaceDelta, P = GridUpdate> {
pub(crate) base_projection_revision: u64,
pub(crate) base_surface_revision: u64,
pub(crate) surface: S,
pub(crate) rows: R,
pub(crate) popup_cells: Option
,
}
#[derive(Serialize, Deserialize)]
pub(crate) enum GridUpdate {
Patch(Vec),
Replace(Vec),
}
#[cfg(test)]
pub(crate) fn decode(data: &str) -> Result, String> {
decode::decode(data, None)
}
pub(crate) fn decode_for(
data: &str,
expected: (u16, u16),
) -> Result, String> {
decode::decode(data, Some(expected))
}
pub(crate) fn apply_rows(cells: &mut [CellData], width: u16, rows: &[PaneSurfacePatchRow]) {
for row in rows {
let start = usize::from(row.y) * usize::from(width) + usize::from(row.x);
cells[start..start + row.cells.len()].clone_from_slice(&row.cells);
}
}
#[derive(Serialize)]
struct CellSpan<'a> {
x: u16,
y: u16,
cells: &'a [CellData],
}
#[derive(Serialize)]
enum GridUpdateRef<'a> {
Patch(Vec>),
Replace(&'a [CellData]),
}
fn changed_rows<'a>(
last: &[CellData],
next: &'a [CellData],
width: u16,
full_size: usize,
) -> Result