use std::ops::Range;
use std::pin::Pin;
use futures_util::Stream;
use serde::{Deserialize, Serialize};
use crate::error::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Revision(pub u64);
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct RowId(pub String);
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct Query {
pub start: usize,
pub end: usize,
pub sort: Option<SortSpec>,
pub filter: Option<Filter>,
}
impl Query {
pub fn range(&self) -> Range<usize> {
self.start..self.end
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SortSpec {
pub column: String,
pub descending: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Filter {
pub expression: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum Cell {
Text {
value: String,
},
Number {
value: i64,
},
Timestamp {
millis: i64,
},
Redacted,
Status {
level: StatusLevel,
label_key: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum StatusLevel {
Ok,
Info,
Warning,
Error,
Pending,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Row {
pub id: RowId,
pub cells: Vec<Cell>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Page {
pub rows: Vec<Row>,
pub total: usize,
pub revision: Revision,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum RowPatch {
Upsert { id: RowId, row: Row },
Remove { id: RowId },
}
#[async_trait::async_trait]
pub trait DataPlane: Send + Sync {
async fn query(&self, query: &Query) -> Result<Page, Error>;
fn subscribe(&self, from: Revision) -> Pin<Box<dyn Stream<Item = RowPatch> + Send>>;
}