notion_api_client/models/
properties.rs

1use crate::models::text::RichText;
2use crate::models::users::User;
3
4use crate::ids::{DatabaseId, PageId, PropertyId};
5use crate::models::{DateTime, Number, Utc};
6use chrono::NaiveDate;
7use serde::{Deserialize, Serialize};
8
9pub mod formulas;
10
11#[cfg(test)]
12mod tests;
13
14/// How the number is displayed in Notion.
15#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone, Hash)]
16#[serde(rename_all = "snake_case")]
17pub enum NumberFormat {
18    Number,
19    NumberWithCommas,
20    Percent,
21    Dollar,
22    Euro,
23    Pound,
24    Yen,
25    Ruble,
26    Rupee,
27    Won,
28    Yuan,
29}
30
31#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Hash, Clone)]
32pub struct NumberDetails {
33    pub format: NumberFormat,
34}
35
36#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)]
37#[serde(transparent)]
38pub struct SelectOptionId(String);
39
40#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone)]
41#[serde(rename_all = "lowercase")]
42pub enum Color {
43    Default,
44    Gray,
45    Brown,
46    Orange,
47    Yellow,
48    Green,
49    Blue,
50    Purple,
51    Pink,
52    Red,
53}
54
55#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
56pub struct SelectOption {
57    pub name: String,
58    pub id: SelectOptionId,
59    pub color: Color,
60}
61
62#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
63pub struct Select {
64    /// Sorted list of options available for this property.
65    pub options: Vec<SelectOption>,
66}
67
68#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
69pub struct StatusGroupOption {
70    pub name: String,
71    pub id: SelectOptionId,
72    pub color: Color,
73    pub option_ids: Vec<SelectOptionId>,
74}
75
76#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
77pub struct Status {
78    /// Sorted list of options available for this property.
79    pub options: Vec<SelectOption>,
80    /// Sorted list of groups available for this property.
81    pub groups: Vec<StatusGroupOption>,
82}
83
84#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
85pub struct Formula {
86    /// Formula to evaluate for this property
87    pub expression: String,
88}
89
90#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
91pub struct Relation {
92    /// The database this relation refers to.
93    /// New linked pages must belong to this database in order to be valid.
94    pub database_id: DatabaseId,
95    /// By default, relations are formed as two synced properties across databases:
96    ///     if you make a change to one property, it updates the synced property at the same time.
97    /// `synced_property_name` refers to the name of the property in the related database.
98    pub synced_property_name: Option<String>,
99    /// By default, relations are formed as two synced properties across databases:
100    ///     if you make a change to one property, it updates the synced property at the same time.
101    /// `synced_property_id` refers to the id of the property in the related database.
102    /// This is usually a short string of random letters and symbols.
103    pub synced_property_id: Option<PropertyId>,
104}
105
106/// The function used to roll up the values of the relation property.
107/// <https://developers.notion.com/reference/page-property-values#rollup>
108#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone)]
109#[serde(rename_all = "snake_case")]
110pub enum RollupFunction {
111    Average,
112    Checked,
113    Count,
114    CountPerGroup,
115    CountValues,
116    DateRange,
117    EarliestDate,
118    Empty,
119    LatestDate,
120    Max,
121    Median,
122    Min,
123    NotEmpty,
124    PercentChecked,
125    PercentEmpty,
126    PercentNotEmpty,
127    PercentPerGroup,
128    PercentUnchecked,
129    Range,
130    ShowOriginal,
131    ShowUnique,
132    Sum,
133    Unchecked,
134    Unique,
135}
136
137#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
138pub struct Rollup {
139    /// The name of the relation property this property is responsible for rolling up.
140    pub relation_property_name: String,
141    /// The id of the relation property this property is responsible for rolling up.
142    pub relation_property_id: PropertyId,
143    /// The name of the property of the pages in the related database
144    /// that is used as an input to `function`.
145    pub rollup_property_name: String,
146    /// The id of the property of the pages in the related database
147    /// that is used as an input to `function`.
148    pub rollup_property_id: String,
149    /// The function that is evaluated for every page in the relation of the rollup.
150    pub function: RollupFunction,
151}
152
153#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
154#[serde(tag = "type")]
155#[serde(rename_all = "snake_case")]
156pub enum PropertyConfiguration {
157    /// Represents the special Title property required on every database.
158    /// See <https://developers.notion.com/reference/database#title-configuration>
159    Title { id: PropertyId },
160    /// Represents a Text property
161    /// <https://developers.notion.com/reference/database#text-configuration>
162    #[serde(rename = "rich_text")]
163    Text { id: PropertyId },
164    /// Represents a Number Property
165    /// See <https://developers.notion.com/reference/database#number-configuration>
166    Number {
167        id: PropertyId,
168        /// How the number is displayed in Notion.
169        number: NumberDetails,
170    },
171    /// Represents a Select Property
172    /// See <https://developers.notion.com/reference/database#select-configuration>
173    Select { id: PropertyId, select: Select },
174    /// Represents a Status property
175    Status { id: PropertyId, status: Status },
176    /// Represents a Multi-select Property
177    /// See <https://developers.notion.com/reference/database#multi-select-configuration>
178    MultiSelect {
179        id: PropertyId,
180        multi_select: Select,
181    },
182    /// Represents a Date Property
183    /// See <https://developers.notion.com/reference/database#date-configuration>
184    Date { id: PropertyId },
185    /// Represents a People Property
186    /// See <https://developers.notion.com/reference/database#people-configuration>
187    People { id: PropertyId },
188    /// Represents a File Property
189    /// See <https://developers.notion.com/reference/database#file-configuration>
190    // Todo: File a bug with notion
191    //       Documentation issue: docs claim type name is `file` but it is in fact `files`
192    Files { id: PropertyId },
193    /// Represents a Checkbox Property
194    /// See <https://developers.notion.com/reference/database#checkbox-configuration>
195    Checkbox { id: PropertyId },
196    /// Represents a URL Property
197    /// See <https://developers.notion.com/reference/database#url-configuration>
198    Url { id: PropertyId },
199    /// Represents a Email Property
200    /// See <https://developers.notion.com/reference/database#email-configuration>
201    Email { id: PropertyId },
202    /// Represents a Phone number Property
203    /// See <https://developers.notion.com/reference/database#phone-number-configuration>
204    PhoneNumber { id: PropertyId },
205    /// See <https://developers.notion.com/reference/database#formula-configuration>
206    Formula { id: PropertyId, formula: Formula },
207    /// See <https://developers.notion.com/reference/database#relation-configuration>
208    Relation { id: PropertyId, relation: Relation },
209    /// See <https://developers.notion.com/reference/database#rollup-configuration>
210    Rollup { id: PropertyId, rollup: Rollup },
211    /// See <https://developers.notion.com/reference/database#created-time-configuration>
212    CreatedTime { id: PropertyId },
213    /// See <https://developers.notion.com/reference/database#created-by-configuration>
214    CreatedBy { id: PropertyId },
215    /// See <https://developers.notion.com/reference/database#last-edited-time-configuration>
216    LastEditedTime { id: PropertyId },
217    /// See <https://developers.notion.com/reference/database#last-edited-by-configuration>
218    LastEditBy { id: PropertyId },
219}
220
221#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
222pub struct SelectedValue {
223    #[serde(skip_serializing_if = "Option::is_none")]
224    pub id: Option<SelectOptionId>,
225    #[serde(skip_serializing_if = "Option::is_none")]
226    pub name: Option<String>,
227    pub color: Color,
228}
229
230#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
231#[serde(untagged)]
232pub enum DateOrDateTime {
233    Date(NaiveDate),
234    DateTime(DateTime<Utc>),
235}
236
237#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
238pub struct DateValue {
239    pub start: DateOrDateTime,
240    pub end: Option<DateOrDateTime>,
241    pub time_zone: Option<String>,
242}
243
244/// Formula property value objects represent the result of evaluating a formula
245/// described in the database's properties.
246#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
247#[serde(tag = "type")]
248#[serde(rename_all = "snake_case")]
249pub enum FormulaResultValue {
250    String { string: Option<String> },
251    Number { number: Option<Number> },
252    Boolean { boolean: Option<bool> },
253    Date { date: Option<DateValue> },
254}
255
256/// Relation property value objects contain an array of page references within the relation property.
257/// A page reference is an object with an id property,
258/// with a string value (UUIDv4) corresponding to a page ID in another database.
259#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
260pub struct RelationValue {
261    pub id: PageId,
262}
263
264#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
265#[serde(tag = "type", rename_all = "snake_case")]
266pub enum RollupValue {
267    Number { number: Option<Number> },
268    Date { date: Option<DateTime<Utc>> },
269    Array { array: Vec<RollupPropertyValue> },
270}
271
272#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
273pub struct FileReference {
274    pub name: String,
275    pub url: String,
276    pub mime_type: String,
277}
278
279#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
280#[serde(tag = "type")]
281#[serde(rename_all = "snake_case")]
282pub enum PropertyValue {
283    // <https://developers.notion.com/reference/property-object#title-configuration>
284    Title {
285        id: PropertyId,
286        title: Vec<RichText>,
287    },
288    /// <https://developers.notion.com/reference/property-object#text-configuration>
289    #[serde(rename = "rich_text")]
290    Text {
291        id: PropertyId,
292        rich_text: Vec<RichText>,
293    },
294    /// <https://developers.notion.com/reference/property-object#number-configuration>
295    Number {
296        id: PropertyId,
297        number: Option<Number>,
298    },
299    /// <https://developers.notion.com/reference/property-object#select-configuration>
300    Select {
301        id: PropertyId,
302        select: Option<SelectedValue>,
303    },
304    /// <https://developers.notion.com/reference/property-object#status-configuration>
305    Status {
306        id: PropertyId,
307        status: Option<SelectedValue>,
308    },
309    /// <https://developers.notion.com/reference/property-object#multi-select-configuration>
310    MultiSelect {
311        id: PropertyId,
312        multi_select: Option<Vec<SelectedValue>>,
313    },
314    /// <https://developers.notion.com/reference/property-object#date-configuration>
315    Date {
316        id: PropertyId,
317        date: Option<DateValue>,
318    },
319    /// <https://developers.notion.com/reference/property-object#formula-configuration>
320    Formula {
321        id: PropertyId,
322        formula: FormulaResultValue,
323    },
324    /// <https://developers.notion.com/reference/property-object#relation-configuration>
325    /// It is actually an array of relations
326    Relation {
327        id: PropertyId,
328        relation: Option<Vec<RelationValue>>,
329    },
330    /// <https://developers.notion.com/reference/property-object#rollup-configuration>
331    Rollup {
332        id: PropertyId,
333        rollup: Option<RollupValue>,
334    },
335    /// <https://developers.notion.com/reference/property-object#people-configuration>
336    People { id: PropertyId, people: Vec<User> },
337    /// <https://developers.notion.com/reference/property-object#files-configuration>
338    Files {
339        id: PropertyId,
340        files: Option<Vec<FileReference>>,
341    },
342    /// <https://developers.notion.com/reference/property-object#checkbox-configuration>
343    Checkbox { id: PropertyId, checkbox: bool },
344    /// <https://developers.notion.com/reference/property-object#url-configuration>
345    Url { id: PropertyId, url: Option<String> },
346    /// <https://developers.notion.com/reference/property-object#email-configuration>
347    Email {
348        id: PropertyId,
349        email: Option<String>,
350    },
351    /// <https://developers.notion.com/reference/property-object#phone-number-configuration>
352    PhoneNumber {
353        id: PropertyId,
354        phone_number: String,
355    },
356    /// <https://developers.notion.com/reference/property-object#created-time-configuration>
357    CreatedTime {
358        id: PropertyId,
359        created_time: DateTime<Utc>,
360    },
361    /// <https://developers.notion.com/reference/property-object#created-by-configuration>
362    CreatedBy { id: PropertyId, created_by: User },
363    /// <https://developers.notion.com/reference/property-object#last-edited-time-configuration>
364    LastEditedTime {
365        id: PropertyId,
366        last_edited_time: DateTime<Utc>,
367    },
368    /// <https://developers.notion.com/reference/property-object#last-edited-by-configuration>
369    LastEditedBy {
370        id: PropertyId,
371        last_edited_by: User,
372    },
373}
374
375/// <https://developers.notion.com/reference/page#rollup-property-value-element>
376#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
377#[serde(tag = "type")]
378#[serde(rename_all = "snake_case")]
379pub enum RollupPropertyValue {
380    /// <https://developers.notion.com/reference/page#rich-text-property-values>
381    #[serde(rename = "rich_text")]
382    Text {
383        rich_text: Vec<RichText>,
384    },
385    /// <https://developers.notion.com/reference/page#number-property-values>
386    Number {
387        number: Option<Number>,
388    },
389    /// <https://developers.notion.com/reference/page#select-property-values>
390    Select {
391        select: Option<SelectedValue>,
392    },
393    Status {
394        status: Option<SelectedValue>,
395    },
396    MultiSelect {
397        multi_select: Option<Vec<SelectedValue>>,
398    },
399    Date {
400        date: Option<DateValue>,
401    },
402    /// <https://developers.notion.com/reference/page#formula-property-values>
403    Formula {
404        formula: FormulaResultValue,
405    },
406    /// <https://developers.notion.com/reference/page#relation-property-values>
407    /// It is actually an array of relations
408    Relation {
409        relation: Option<Vec<RelationValue>>,
410    },
411    /// <https://developers.notion.com/reference/page#rollup-property-values>
412    Rollup {
413        rollup: Option<RollupValue>,
414    },
415    People {
416        people: Vec<User>,
417    },
418    Files {
419        files: Option<Vec<FileReference>>,
420    },
421    Checkbox {
422        checkbox: bool,
423    },
424    Url {
425        url: Option<String>,
426    },
427    Email {
428        email: Option<String>,
429    },
430    PhoneNumber {
431        phone_number: String,
432    },
433    CreatedTime {
434        created_time: DateTime<Utc>,
435    },
436    CreatedBy {
437        created_by: User,
438    },
439    LastEditedTime {
440        last_edited_time: DateTime<Utc>,
441    },
442    LastEditedBy {
443        last_edited_by: User,
444    },
445}