use super::{TableColumnDefinition, TableColumnId, TableRow, TableRowValue};
use crate::data_sources::SelectedDataSource;
use crate::formatting::Formatting;
use crate::front_matter_schemas::{FrontMatterSchemaEntry, FrontMatterValueSchema};
use crate::notebooks::{Cell, FrontMatter, Label};
use crate::timestamps::TimeRange;
#[cfg(feature = "fp-bindgen")]
use fp_bindgen::prelude::*;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use typed_builder::TypedBuilder;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum Operation {
MoveCells(MoveCellsOperation),
ReplaceCells(ReplaceCellsOperation),
ReplaceText(ReplaceTextOperation),
UpdateNotebookTimeRange(UpdateNotebookTimeRangeOperation),
UpdateNotebookTitle(UpdateNotebookTitleOperation),
SetSelectedDataSource(SetSelectedDataSourceOperation),
AddLabel(AddLabelOperation),
ReplaceLabel(ReplaceLabelOperation),
RemoveLabel(RemoveLabelOperation),
ClearFrontMatter(ClearFrontMatterOperation),
InsertFrontMatterSchema(InsertFrontMatterSchemaOperation),
UpdateFrontMatterSchema(UpdateFrontMatterSchemaOperation),
MoveFrontMatterSchema(MoveFrontMatterSchemaOperation),
RemoveFrontMatterSchema(RemoveFrontMatterSchemaOperation),
UpdateFrontMatter(UpdateFrontMatterOperation),
InsertTableColumn(InsertTableColumnOperation),
RemoveTableColumn(RemoveTableColumnOperation),
UpdateTableColumnDefinition(UpdateTableColumnDefinitionOperation),
InsertTableRow(InsertTableRowOperation),
RemoveTableRow(RemoveTableRowOperation),
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct MoveCellsOperation {
pub cell_ids: Vec<String>,
pub from_index: u32,
pub to_index: u32,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct ReplaceCellsOperation {
#[builder(default)]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub new_cells: Vec<CellWithIndex>,
#[builder(default)]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub old_cells: Vec<CellWithIndex>,
#[builder(default, setter(strip_option))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub split_offset: Option<u32>,
#[builder(default, setter(strip_option))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub merge_offset: Option<u32>,
#[builder(default)]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub new_referencing_cells: Vec<CellWithIndex>,
#[builder(default)]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub old_referencing_cells: Vec<CellWithIndex>,
}
impl ReplaceCellsOperation {
pub fn all_new_cells(&self) -> impl Iterator<Item = &CellWithIndex> {
self.old_cells
.iter()
.chain(self.old_referencing_cells.iter())
}
pub fn all_newly_inserted_cells(&self) -> impl Iterator<Item = &CellWithIndex> {
self.newly_inserted_cells()
.chain(self.newly_inserted_referencing_cells())
}
pub fn all_old_cells(&self) -> impl Iterator<Item = &CellWithIndex> {
self.old_cells
.iter()
.chain(self.old_referencing_cells.iter())
}
pub fn all_old_removed_cells(&self) -> impl Iterator<Item = &CellWithIndex> {
self.old_removed_cells()
.chain(self.old_removed_referencing_cells())
}
pub fn newly_inserted_cells(&self) -> impl Iterator<Item = &CellWithIndex> {
self.new_cells.iter().filter(move |new_cell| {
!self
.old_cells
.iter()
.any(|old_cell| old_cell.id() == new_cell.id())
})
}
pub fn newly_inserted_referencing_cells(&self) -> impl Iterator<Item = &CellWithIndex> {
self.new_referencing_cells.iter().filter(move |new_cell| {
!self
.old_referencing_cells
.iter()
.any(|old_cell| old_cell.id() == new_cell.id())
})
}
pub fn old_removed_cells(&self) -> impl Iterator<Item = &CellWithIndex> {
self.old_cells.iter().filter(move |old_cell| {
!self
.new_cells
.iter()
.any(|new_cell| new_cell.id() == old_cell.id())
})
}
pub fn old_removed_referencing_cells(&self) -> impl Iterator<Item = &CellWithIndex> {
self.old_referencing_cells.iter().filter(move |old_cell| {
!self
.new_referencing_cells
.iter()
.any(|new_cell| new_cell.id() == old_cell.id())
})
}
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct ReplaceTextOperation {
#[builder(setter(into))]
pub cell_id: String,
#[builder(default, setter(into, strip_option))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub field: Option<String>,
pub offset: u32,
#[builder(default, setter(into))]
pub new_text: String,
#[builder(default, setter(strip_option))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub new_formatting: Option<Formatting>,
#[builder(default, setter(into))]
pub old_text: String,
#[builder(default, setter(strip_option))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub old_formatting: Option<Formatting>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct UpdateNotebookTimeRangeOperation {
pub old_time_range: TimeRange,
pub time_range: TimeRange,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct UpdateNotebookTitleOperation {
#[builder(default, setter(into))]
pub old_title: String,
#[builder(default, setter(into))]
pub title: String,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct SetSelectedDataSourceOperation {
#[builder(setter(into))]
pub provider_type: String,
#[builder(default)]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub old_selected_data_source: Option<SelectedDataSource>,
#[builder(default)]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub new_selected_data_source: Option<SelectedDataSource>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct CellWithIndex {
pub cell: Cell,
pub index: u32,
}
impl CellWithIndex {
pub fn new(cell: Cell, index: u32) -> CellWithIndex {
CellWithIndex { cell, index }
}
pub fn formatting(&self) -> Option<&Formatting> {
self.cell.formatting()
}
pub fn id(&self) -> &str {
self.cell.id()
}
pub fn text(&self) -> Option<&str> {
self.cell.text()
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct AddLabelOperation {
pub label: Label,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct ReplaceLabelOperation {
pub old_label: Label,
pub new_label: Label,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct RemoveLabelOperation {
pub label: Label,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct UpdateFrontMatterOperation {
pub old_front_matter: FrontMatter,
pub new_front_matter: FrontMatter,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct ClearFrontMatterOperation {
pub front_matter: FrontMatter,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct InsertFrontMatterSchemaOperation {
#[builder(default, setter(into))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub key_of_entry_before_insertion_location: Option<String>,
#[builder(default, setter(into))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub key_of_entry_after_insertion_location: Option<String>,
pub to_index: u32,
pub insertions: Vec<FrontMatterSchemaRow>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct FrontMatterSchemaRow {
#[builder(setter(into))]
pub key: String,
#[builder(setter(into))]
pub schema: FrontMatterValueSchema,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into))]
pub value: Option<Value>,
}
impl From<(FrontMatterSchemaEntry, Option<Value>)> for FrontMatterSchemaRow {
fn from((schema, value): (FrontMatterSchemaEntry, Option<Value>)) -> Self {
Self {
key: schema.key,
schema: schema.schema,
value,
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct UpdateFrontMatterSchemaOperation {
#[builder(setter(into))]
pub key: String,
#[builder(setter(into))]
pub old_schema: FrontMatterValueSchema,
#[builder(default)]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub old_value: Option<Value>,
#[builder(setter(into))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub new_schema: Option<FrontMatterValueSchema>,
#[builder(default)]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub new_value: Option<Value>,
#[builder(setter(strip_bool))]
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub delete_value: bool,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct MoveFrontMatterSchemaOperation {
pub keys: Vec<String>,
pub from_index: u32,
pub to_index: u32,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct RemoveFrontMatterSchemaOperation {
#[builder(default, setter(into))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub key_of_entry_before_deletion_range: Option<String>,
#[builder(default, setter(into))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub key_of_entry_after_deletion_range: Option<String>,
pub from_index: u32,
pub deletions: Vec<FrontMatterSchemaRow>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct CellAppendText {
#[builder(setter(into))]
pub content: String,
#[builder(default)]
#[serde(default)]
pub formatting: Formatting,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct CellReplaceText {
pub offset: u32,
#[builder(default, setter(into))]
pub new_text: String,
#[builder(default, setter(strip_option))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub new_formatting: Option<Formatting>,
#[builder(default, setter(into))]
pub old_text: String,
#[builder(default, setter(strip_option))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub old_formatting: Option<Formatting>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct InsertTableColumnOperation {
#[builder(setter(into))]
pub cell_id: String,
pub column_def: TableColumnDefinition,
pub index: u32,
#[builder(setter(into))]
pub values: Vec<TableRowValue>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct RemoveTableColumnOperation {
#[builder(setter(into))]
pub cell_id: String,
pub column_def: TableColumnDefinition,
pub index: u32,
#[builder(setter(into))]
pub values: Vec<TableRowValue>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct UpdateTableColumnDefinitionOperation {
#[builder(setter(into))]
pub cell_id: String,
pub column_id: TableColumnId,
#[builder(setter(into))]
pub new_title: String,
#[builder(setter(into))]
pub old_title: String,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct InsertTableRowOperation {
#[builder(setter(into))]
pub cell_id: String,
pub row: TableRow,
pub index: u32,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::notebooks::operations")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct RemoveTableRowOperation {
#[builder(setter(into))]
pub cell_id: String,
pub row: TableRow,
pub index: u32,
}