use crate::notebooks::{
front_matter::{
FrontMatterDateTimeValue, FrontMatterNumberValue, FrontMatterStringList,
FrontMatterStringValue, FrontMatterUserList, FrontMatterUserValue,
FrontMatterValidationError, FrontMatterValue,
},
operations::FrontMatterSchemaRow,
};
#[cfg(feature = "fp-bindgen")]
use fp_bindgen::prelude::Serializable;
use ordered_float::OrderedFloat;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use strum_macros::Display;
use typed_builder::TypedBuilder;
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, Default)]
#[repr(transparent)]
pub struct SerializableEqFloat(pub OrderedFloat<f64>);
#[cfg(feature = "fp-bindgen")]
impl Serializable for SerializableEqFloat {
fn ident() -> fp_bindgen::types::TypeIdent {
fp_bindgen::types::TypeIdent::from("f64")
}
fn ty() -> fp_bindgen::types::Type {
fp_bindgen::types::Type::Custom(fp_bindgen::types::CustomType {
ident: fp_bindgen::types::TypeIdent::from("SerializableEqFloat"),
rs_ty: "f64".to_owned(),
ts_ty: "number".to_owned(),
rs_dependencies: std::collections::BTreeMap::new(),
serde_attrs: Vec::new(),
ts_declaration: None,
})
}
}
impl<T: Into<f64>> From<T> for SerializableEqFloat {
fn from(value: T) -> Self {
Self(OrderedFloat(value.into()))
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, Default)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::front_matter_schemas")
)]
#[repr(transparent)]
pub struct FrontMatterSchema(pub Vec<FrontMatterSchemaEntry>);
impl std::ops::Deref for FrontMatterSchema {
type Target = Vec<FrontMatterSchemaEntry>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::ops::DerefMut for FrontMatterSchema {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<Vec<FrontMatterSchemaEntry>> for FrontMatterSchema {
fn from(value: Vec<FrontMatterSchemaEntry>) -> Self {
Self(value)
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::front_matter_schemas")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct FrontMatterSchemaEntry {
#[builder(setter(into))]
pub key: String,
#[builder(setter(into))]
pub schema: FrontMatterValueSchema,
}
impl FrontMatterSchemaEntry {
pub fn validate_value(
&self,
value: serde_json::Value,
) -> Result<FrontMatterValue, FrontMatterValidationError> {
self.schema.validate_value(value)
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, Display)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::front_matter_schemas")
)]
#[non_exhaustive]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum FrontMatterValueSchema {
Number(FrontMatterNumberSchema),
String(FrontMatterStringSchema),
DateTime(FrontMatterDateTimeSchema),
User(FrontMatterUserSchema),
}
impl FrontMatterValueSchema {
pub fn validate_value(
&self,
value: serde_json::Value,
) -> Result<FrontMatterValue, FrontMatterValidationError> {
match self {
FrontMatterValueSchema::Number(schema) => schema.validate_value(value),
FrontMatterValueSchema::String(schema) => schema.validate_value(value),
FrontMatterValueSchema::DateTime(schema) => schema.validate_value(value),
FrontMatterValueSchema::User(schema) => schema.validate_value(value),
}
}
pub fn validate_front_matter_value(
&self,
value: &FrontMatterValue,
) -> Result<(), FrontMatterValidationError> {
match self {
FrontMatterValueSchema::Number(schema) => schema.validate_front_matter_value(value),
FrontMatterValueSchema::String(schema) => schema.validate_front_matter_value(value),
FrontMatterValueSchema::DateTime(schema) => schema.validate_front_matter_value(value),
FrontMatterValueSchema::User(schema) => schema.validate_front_matter_value(value),
}
}
}
impl FrontMatterNumberSchema {
pub fn validate_value(
&self,
value: serde_json::Value,
) -> Result<FrontMatterValue, FrontMatterValidationError> {
Ok(FrontMatterNumberValue::try_from(value)?.into())
}
pub fn validate_front_matter_value(
&self,
value: &FrontMatterValue,
) -> Result<(), FrontMatterValidationError> {
match value {
FrontMatterValue::Number(_) => Ok(()),
other => Err(FrontMatterValidationError::wrong_variant(
other.get_type(),
"number",
)),
}
}
}
impl FrontMatterStringSchema {
pub fn validate_value(
&self,
value: serde_json::Value,
) -> Result<FrontMatterValue, FrontMatterValidationError> {
if self.multiple {
Ok(FrontMatterStringList::try_from(value)?.into())
} else {
Ok(FrontMatterStringValue::try_from(value)?.into())
}
}
pub fn validate_front_matter_value(
&self,
value: &FrontMatterValue,
) -> Result<(), FrontMatterValidationError> {
match (value, self.multiple) {
(FrontMatterValue::String(_), false) => Ok(()),
(FrontMatterValue::StringList(_), true) => Ok(()),
(other, true) => Err(FrontMatterValidationError::wrong_variant(
other.get_type(),
"string_list",
)),
(other, false) => Err(FrontMatterValidationError::wrong_variant(
other.get_type(),
"string",
)),
}
}
}
impl FrontMatterDateTimeSchema {
pub fn validate_value(
&self,
value: serde_json::Value,
) -> Result<FrontMatterValue, FrontMatterValidationError> {
Ok(FrontMatterDateTimeValue::try_from(value)?.into())
}
pub fn validate_front_matter_value(
&self,
value: &FrontMatterValue,
) -> Result<(), FrontMatterValidationError> {
match value {
FrontMatterValue::DateTime(_) => Ok(()),
other => Err(FrontMatterValidationError::wrong_variant(
other.get_type(),
"date_time",
)),
}
}
}
impl FrontMatterUserSchema {
pub fn validate_value(
&self,
value: serde_json::Value,
) -> Result<FrontMatterValue, FrontMatterValidationError> {
if self.multiple {
Ok(FrontMatterUserList::try_from(value)?.into())
} else {
Ok(FrontMatterUserValue::try_from(value)?.into())
}
}
pub fn validate_front_matter_value(
&self,
value: &FrontMatterValue,
) -> Result<(), FrontMatterValidationError> {
match (value, self.multiple) {
(FrontMatterValue::User(_), false) => Ok(()),
(FrontMatterValue::UserList(_), true) => Ok(()),
(other, true) => Err(FrontMatterValidationError::wrong_variant(
other.get_type(),
"user_list",
)),
(other, false) => Err(FrontMatterValidationError::wrong_variant(
other.get_type(),
"user",
)),
}
}
}
impl From<FrontMatterUserSchema> for FrontMatterValueSchema {
fn from(v: FrontMatterUserSchema) -> Self {
Self::User(v)
}
}
impl From<FrontMatterDateTimeSchema> for FrontMatterValueSchema {
fn from(v: FrontMatterDateTimeSchema) -> Self {
Self::DateTime(v)
}
}
impl From<FrontMatterStringSchema> for FrontMatterValueSchema {
fn from(v: FrontMatterStringSchema) -> Self {
Self::String(v)
}
}
impl From<FrontMatterNumberSchema> for FrontMatterValueSchema {
fn from(v: FrontMatterNumberSchema) -> Self {
Self::Number(v)
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::front_matter_schemas")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct FrontMatterNumberSchema {
#[builder(default, setter(into))]
pub display_name: String,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub icon_name: Option<String>,
#[builder(setter(strip_bool))]
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub allow_extra_values: bool,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<Vec<FrontMatterNumberValue>>,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub default_value: Option<FrontMatterNumberValue>,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub prefix: Option<String>,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub suffix: Option<String>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::front_matter_schemas")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct FrontMatterStringSchema {
#[builder(default, setter(into))]
pub display_name: String,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub icon_name: Option<String>,
#[builder(setter(strip_bool))]
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub multiple: bool,
#[builder(setter(strip_bool))]
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub allow_extra_values: bool,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<Vec<FrontMatterStringValue>>,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub default_value: Option<FrontMatterStringValue>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::front_matter_schemas")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct FrontMatterDateTimeSchema {
#[builder(default, setter(into))]
pub display_name: String,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub icon_name: Option<String>,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub default_value: Option<FrontMatterDateTimeValue>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::front_matter_schemas")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct FrontMatterUserSchema {
#[builder(default, setter(into))]
pub display_name: String,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub icon_name: Option<String>,
#[builder(default, setter(into, strip_option))]
#[serde(skip_serializing_if = "Option::is_none")]
pub default_value: Option<FrontMatterUserValue>,
#[builder(setter(strip_bool))]
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub multiple: bool,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::front_matter_schemas")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct FrontMatterUpdateRow {
#[builder(default, setter(into, strip_option))]
#[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::front_matter_schemas")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct FrontMatterAddRows {
pub to_index: u32,
pub insertions: Vec<FrontMatterSchemaRow>,
}