use crate::models::text::RichText; use crate::models::users::User; use super::{DateTime, Number, Utc}; use crate::ids::{DatabaseId, PageId, PropertyId}; use chrono::NaiveDate; use serde::{Deserialize, Serialize}; pub mod formulas; #[cfg(test)] mod tests; /// How the number is displayed in Notion. #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone, Hash)] #[serde(rename_all = "snake_case")] pub enum NumberFormat { Number, NumberWithCommas, Percent, Dollar, Euro, Pound, Yen, Ruble, Rupee, Won, Yuan, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Hash, Clone)] pub struct NumberDetails { pub format: NumberFormat, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] #[serde(transparent)] pub struct SelectOptionId(String); #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone)] #[serde(rename_all = "lowercase")] pub enum Color { Default, Gray, Brown, Orange, Yellow, Green, Blue, Purple, Pink, Red, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct SelectOption { pub name: String, pub id: SelectOptionId, pub color: Color, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct Select { /// Sorted list of options available for this property. pub options: Vec, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct Formula { /// Formula to evaluate for this property pub expression: String, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct Relation { /// The database this relation refers to. /// New linked pages must belong to this database in order to be valid. pub database_id: DatabaseId, /// By default, relations are formed as two synced properties across databases: /// if you make a change to one property, it updates the synced property at the same time. /// `synced_property_name` refers to the name of the property in the related database. pub synced_property_name: Option, /// By default, relations are formed as two synced properties across databases: /// if you make a change to one property, it updates the synced property at the same time. /// `synced_property_id` refers to the id of the property in the related database. /// This is usually a short string of random letters and symbols. pub synced_property_id: Option, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone)] #[serde(rename_all = "snake_case")] pub enum RollupFunction { CountAll, CountValues, CountUniqueValues, CountEmpty, CountNotEmpty, PercentEmpty, PercentNotEmpty, Sum, Average, Median, Min, Max, Range, ShowOriginal, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct Rollup { /// The name of the relation property this property is responsible for rolling up. pub relation_property_name: String, /// The id of the relation property this property is responsible for rolling up. pub relation_property_id: PropertyId, /// The name of the property of the pages in the related database /// that is used as an input to `function`. pub rollup_property_name: String, /// The id of the property of the pages in the related database /// that is used as an input to `function`. pub rollup_property_id: String, /// The function that is evaluated for every page in the relation of the rollup. pub function: RollupFunction, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] #[serde(tag = "type")] #[serde(rename_all = "snake_case")] pub enum PropertyConfiguration { /// Represents the special Title property required on every database. /// See Title { id: PropertyId }, /// Represents a Text property /// #[serde(rename = "rich_text")] Text { id: PropertyId }, /// Represents a Number Property /// See Number { id: PropertyId, /// How the number is displayed in Notion. number: NumberDetails, }, /// Represents a Select Property /// See Select { id: PropertyId, select: Select }, /// Represents a Multi-select Property /// See MultiSelect { id: PropertyId, multi_select: Select, }, /// Represents a Date Property /// See Date { id: PropertyId }, /// Represents a People Property /// See People { id: PropertyId }, /// Represents a File Property /// See // Todo: File a bug with notion // Documentation issue: docs claim type name is `file` but it is in fact `files` Files { id: PropertyId }, /// Represents a Checkbox Property /// See Checkbox { id: PropertyId }, /// Represents a URL Property /// See Url { id: PropertyId }, /// Represents a Email Property /// See Email { id: PropertyId }, /// Represents a Phone number Property /// See PhoneNumber { id: PropertyId }, /// See Formula { id: PropertyId, formula: Formula }, /// See Relation { id: PropertyId, relation: Relation }, /// See Rollup { id: PropertyId, rollup: Rollup }, /// See CreatedTime { id: PropertyId }, /// See CreatedBy { id: PropertyId }, /// See LastEditedTime { id: PropertyId }, /// See LastEditBy { id: PropertyId }, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct SelectedValue { pub id: SelectOptionId, pub name: String, pub color: Color, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] #[serde(untagged)] pub enum DateOrDateTime { Date(NaiveDate), DateTime(DateTime), } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct DateValue { pub start: DateOrDateTime, pub end: Option, } /// Formula property value objects represent the result of evaluating a formula /// described in the database's properties. #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] #[serde(tag = "type")] #[serde(rename_all = "snake_case")] pub enum FormulaResultValue { String { string: Option }, Number { number: Option }, Boolean { boolean: Option }, Date { date: Option }, } /// Relation property value objects contain an array of page references within the relation property. /// A page reference is an object with an id property, /// with a string value (UUIDv4) corresponding to a page ID in another database. #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct RelationValue { pub id: PageId, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] #[serde(tag = "type")] #[serde(rename_all = "snake_case")] pub enum RollupValue { Number(#[serde(rename = "number")] Option), Date(#[serde(rename = "date")] Option>), // Todo: these property values don't have id properties... // so this likely wont deserialize. would like to minimize duplicated code... Array(#[serde(rename = "array")] Vec), } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct FileReference { pub name: String, pub url: String, pub mime_type: String, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] #[serde(tag = "type")] #[serde(rename_all = "snake_case")] pub enum PropertyValue { // Title { id: PropertyId, title: Vec, }, /// #[serde(rename = "rich_text")] Text { id: PropertyId, rich_text: Vec, }, /// Number { id: PropertyId, number: Option, }, /// Select { id: PropertyId, select: Option, }, MultiSelect { id: PropertyId, multi_select: Option>, }, Date { id: PropertyId, date: Option, }, /// Formula { id: PropertyId, formula: FormulaResultValue, }, /// /// It is actually an array of relations Relation { id: PropertyId, relation: Option>, }, Rollup { id: PropertyId, relation: Option, }, People { id: PropertyId, people: Vec, }, Files { id: PropertyId, files: Option>, }, Checkbox { id: PropertyId, checkbox: bool, }, Url { id: PropertyId, url: Option, }, Email { id: PropertyId, email: Option, }, PhoneNumber { id: PropertyId, phone_number: String, }, CreatedTime { id: PropertyId, created_time: DateTime, }, CreatedBy { id: PropertyId, created_by: User, }, LastEditedTime { id: PropertyId, last_edited_time: DateTime, }, LastEditedBy { id: PropertyId, last_edited_by: User, }, }