aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jake Swenson <jakeswenson@users.noreply.github.com> 2021-08-28 10:14:39 -0700
committerGravatar GitHub <noreply@github.com> 2021-08-28 17:14:39 +0000
commitc9266553610fd48a66048d9169da4703a0c71716 (patch)
tree0d65a763f646d8b213411328d56b99620123edc2
parent4fa6f626a0fc571b0293d63da78ca37b4e359af1 (diff)
downloadnotion-c9266553610fd48a66048d9169da4703a0c71716.tar.gz
notion-c9266553610fd48a66048d9169da4703a0c71716.tar.zst
notion-c9266553610fd48a66048d9169da4703a0c71716.zip
Number format parsing bug. Fixes #15 (#16)
-rw-r--r--src/lib.rs2
-rw-r--r--src/models.rs68
-rw-r--r--src/models/paging.rs4
-rw-r--r--src/models/properties.rs104
-rw-r--r--src/models/search.rs11
-rw-r--r--src/models/tests/issue_15.json89
-rw-r--r--src/models/text.rs36
7 files changed, 212 insertions, 102 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 28fd426..cba9091 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -94,7 +94,7 @@ impl NotionApi {
}
/// Search all pages in notion.
- /// Query: can either be a [SearchRequest] or a
+ /// `query` can either be a [SearchRequest] or a slightly more convenient
/// [NotionSearch](models::search::NotionSearch) query.
pub async fn search<T: Into<SearchRequest>>(
&self,
diff --git a/src/models.rs b/src/models.rs
index 78ad105..fc31d17 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -39,17 +39,17 @@ impl Display for DatabaseId {
}
/// Represents a Notion Database
-/// See https://developers.notion.com/reference/database
+/// See <https://developers.notion.com/reference/database>
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct Database {
/// Unique identifier for the database.
- id: DatabaseId,
+ pub id: DatabaseId,
/// Date and time when this database was created.
- created_time: DateTime<Utc>,
+ pub created_time: DateTime<Utc>,
/// Date and time when this database was updated.
- last_edited_time: DateTime<Utc>,
+ pub last_edited_time: DateTime<Utc>,
/// Name of the database as it appears in Notion.
- title: Vec<RichText>,
+ pub title: Vec<RichText>,
/// Schema of properties for the database as they appear in Notion.
//
// key string
@@ -57,7 +57,7 @@ pub struct Database {
//
// value object
// A Property object.
- properties: HashMap<String, PropertyConfiguration>,
+ pub properties: HashMap<String, PropertyConfiguration>,
}
impl AsIdentifier<DatabaseId> for Database {
@@ -75,7 +75,7 @@ impl Database {
}
}
-/// https://developers.notion.com/reference/pagination#responses
+/// <https://developers.notion.com/reference/pagination#responses>
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)]
pub struct ListResponse<T> {
pub results: Vec<T>,
@@ -137,51 +137,51 @@ pub enum Parent {
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct Properties {
#[serde(flatten)]
- properties: HashMap<String, PropertyValue>,
+ pub properties: HashMap<String, PropertyValue>,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct Page {
- id: PageId,
+ pub id: PageId,
/// Date and time when this page was created.
- created_time: DateTime<Utc>,
+ pub created_time: DateTime<Utc>,
/// Date and time when this page was updated.
- last_edited_time: DateTime<Utc>,
+ pub last_edited_time: DateTime<Utc>,
/// The archived status of the page.
- archived: bool,
- properties: Properties,
- parent: Parent,
+ pub archived: bool,
+ pub properties: Properties,
+ pub parent: Parent,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct BlockCommon {
- id: BlockId,
- created_time: DateTime<Utc>,
- last_edited_time: DateTime<Utc>,
- has_children: bool,
+ pub id: BlockId,
+ pub created_time: DateTime<Utc>,
+ pub last_edited_time: DateTime<Utc>,
+ pub has_children: bool,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct TextAndChildren {
- text: Vec<RichText>,
- children: Option<Vec<Block>>,
+ pub text: Vec<RichText>,
+ pub children: Option<Vec<Block>>,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct Text {
- text: Vec<RichText>,
+ pub text: Vec<RichText>,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct ToDoFields {
- text: Vec<RichText>,
- checked: bool,
- children: Option<Vec<Block>>,
+ pub text: Vec<RichText>,
+ pub checked: bool,
+ pub children: Option<Vec<Block>>,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct ChildPageFields {
- title: String,
+ pub title: String,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
@@ -339,19 +339,19 @@ impl UserId {
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct UserCommon {
- id: UserId,
- name: Option<String>,
- avatar_url: Option<String>,
+ pub id: UserId,
+ pub name: Option<String>,
+ pub avatar_url: Option<String>,
}
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct Person {
- email: String,
+ pub email: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct Bot {
- email: String,
+ pub email: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
@@ -371,7 +371,7 @@ pub enum User {
#[cfg(test)]
mod tests {
- use crate::models::{ListResponse, Page};
+ use crate::models::{ListResponse, Object, Page};
#[test]
fn deserialize_page() {
@@ -383,4 +383,10 @@ mod tests {
let _page: ListResponse<Page> =
serde_json::from_str(include_str!("models/tests/query_result.json")).unwrap();
}
+
+ #[test]
+ fn deserialize_number_format() {
+ let _search_results: ListResponse<Object> =
+ serde_json::from_str(include_str!("models/tests/issue_15.json")).unwrap();
+ }
}
diff --git a/src/models/paging.rs b/src/models/paging.rs
index 31244a2..3b97301 100644
--- a/src/models/paging.rs
+++ b/src/models/paging.rs
@@ -7,7 +7,7 @@ pub struct PagingCursor(String);
#[derive(Serialize, Debug, Eq, PartialEq, Default)]
pub struct Paging {
#[serde(skip_serializing_if = "Option::is_none")]
- start_cursor: Option<PagingCursor>,
+ pub start_cursor: Option<PagingCursor>,
#[serde(skip_serializing_if = "Option::is_none")]
- page_size: Option<u8>,
+ pub page_size: Option<u8>,
}
diff --git a/src/models/properties.rs b/src/models/properties.rs
index 22689e9..b3948b4 100644
--- a/src/models/properties.rs
+++ b/src/models/properties.rs
@@ -9,8 +9,7 @@ use super::{DateTime, Number, Utc};
pub struct PropertyId(String);
/// How the number is displayed in Notion.
-#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone)]
-#[serde(tag = "type")]
+#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone, Hash)]
#[serde(rename_all = "snake_case")]
pub enum NumberFormat {
Number,
@@ -26,6 +25,11 @@ pub enum NumberFormat {
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);
@@ -47,37 +51,37 @@ pub enum Color {
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct SelectOption {
- name: String,
- id: SelectOptionId,
- color: Color,
+ 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.
- options: Vec<SelectOption>,
+ pub options: Vec<SelectOption>,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct Formula {
/// Formula to evaluate for this property
- expression: String,
+ 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.
- database_id: DatabaseId,
+ 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.
- synced_property_name: Option<String>,
+ pub synced_property_name: Option<String>,
/// 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.
- synced_property_id: Option<PropertyId>,
+ pub synced_property_id: Option<PropertyId>,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Copy, Clone)]
@@ -101,17 +105,17 @@ pub enum RollupFunction {
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct Rollup {
/// The name of the relation property this property is responsible for rolling up.
- relation_property_name: String,
+ pub relation_property_name: String,
/// The id of the relation property this property is responsible for rolling up.
- relation_property_id: PropertyId,
+ 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`.
- rollup_property_name: String,
+ 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`.
- rollup_property_id: String,
+ pub rollup_property_id: String,
/// The function that is evaluated for every page in the relation of the rollup.
- function: RollupFunction,
+ pub function: RollupFunction,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
@@ -119,80 +123,80 @@ pub struct Rollup {
#[serde(rename_all = "snake_case")]
pub enum PropertyConfiguration {
/// Represents the special Title property required on every database.
- /// See https://developers.notion.com/reference/database#title-configuration
+ /// See <https://developers.notion.com/reference/database#title-configuration>
Title { id: PropertyId },
/// Represents a Text property
- /// https://developers.notion.com/reference/database#text-configuration
+ /// <https://developers.notion.com/reference/database#text-configuration>
#[serde(rename = "rich_text")]
Text { id: PropertyId },
/// Represents a Number Property
- /// See https://developers.notion.com/reference/database#number-configuration
+ /// See <https://developers.notion.com/reference/database#number-configuration>
Number {
id: PropertyId,
/// How the number is displayed in Notion.
- format: NumberFormat,
+ number: NumberDetails,
},
/// Represents a Select Property
- /// See https://developers.notion.com/reference/database#select-configuration
+ /// See <https://developers.notion.com/reference/database#select-configuration>
Select { id: PropertyId, select: Select },
/// Represents a Multi-select Property
- /// See https://developers.notion.com/reference/database#multi-select-configuration
+ /// See <https://developers.notion.com/reference/database#multi-select-configuration>
MultiSelect {
id: PropertyId,
multi_select: Select,
},
/// Represents a Date Property
- /// See https://developers.notion.com/reference/database#date-configuration
+ /// See <https://developers.notion.com/reference/database#date-configuration>
Date { id: PropertyId },
/// Represents a People Property
- /// See https://developers.notion.com/reference/database#people-configuration
+ /// See <https://developers.notion.com/reference/database#people-configuration>
People { id: PropertyId },
/// Represents a File Property
- /// See https://developers.notion.com/reference/database#file-configuration
+ /// See <https://developers.notion.com/reference/database#file-configuration>
// 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 https://developers.notion.com/reference/database#checkbox-configuration
+ /// See <https://developers.notion.com/reference/database#checkbox-configuration>
Checkbox { id: PropertyId },
/// Represents a URL Property
- /// See https://developers.notion.com/reference/database#url-configuration
+ /// See <https://developers.notion.com/reference/database#url-configuration>
Url { id: PropertyId },
/// Represents a Email Property
- /// See https://developers.notion.com/reference/database#email-configuration
+ /// See <https://developers.notion.com/reference/database#email-configuration>
Email { id: PropertyId },
/// Represents a Phone number Property
- /// See https://developers.notion.com/reference/database#phone-number-configuration
+ /// See <https://developers.notion.com/reference/database#phone-number-configuration>
PhoneNumber { id: PropertyId },
- /// See https://developers.notion.com/reference/database#formula-configuration
+ /// See <https://developers.notion.com/reference/database#formula-configuration>
Formula { id: PropertyId, formula: Formula },
- /// See https://developers.notion.com/reference/database#relation-configuration
+ /// See <https://developers.notion.com/reference/database#relation-configuration>
Relation { id: PropertyId, relation: Relation },
- /// See https://developers.notion.com/reference/database#rollup-configuration
+ /// See <https://developers.notion.com/reference/database#rollup-configuration>
Rollup { id: PropertyId, rollup: Rollup },
- /// See https://developers.notion.com/reference/database#created-time-configuration
+ /// See <https://developers.notion.com/reference/database#created-time-configuration>
CreatedTime { id: PropertyId },
- /// See https://developers.notion.com/reference/database#created-by-configuration
+ /// See <https://developers.notion.com/reference/database#created-by-configuration>
CreatedBy { id: PropertyId },
- /// See https://developers.notion.com/reference/database#last-edited-time-configuration
+ /// See <https://developers.notion.com/reference/database#last-edited-time-configuration>
LastEditTime { id: PropertyId },
- /// See https://developers.notion.com/reference/database#last-edited-by-configuration
+ /// See <https://developers.notion.com/reference/database#last-edited-by-configuration>
LastEditBy { id: PropertyId },
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct SelectedValue {
- id: SelectOptionId,
- name: String,
- color: Color,
+ pub id: SelectOptionId,
+ pub name: String,
+ pub color: Color,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct DateValue {
// Todo: Will this work with dates (without time)?
// does there need to be an enum of Date|DateTime?
- start: DateTime<Utc>,
- end: Option<DateTime<Utc>>,
+ pub start: DateTime<Utc>,
+ pub end: Option<DateTime<Utc>>,
}
/// Formula property value objects represent the result of evaluating a formula
@@ -212,7 +216,7 @@ pub enum FormulaResultValue {
/// with a string value (UUIDv4) corresponding to a page ID in another database.
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct RelationValue {
- id: PageId,
+ pub id: PageId,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
@@ -228,32 +232,32 @@ pub enum RollupValue {
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct FileReference {
- name: String,
- url: String,
- mime_type: String,
+ 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 {
- // https://developers.notion.com/reference/page#title-property-values
+ // <https://developers.notion.com/reference/page#title-property-values>
Title {
id: PropertyId,
title: Vec<RichText>,
},
- /// https://developers.notion.com/reference/page#rich-text-property-values
+ /// <https://developers.notion.com/reference/page#rich-text-property-values>
#[serde(rename = "rich_text")]
Text {
id: PropertyId,
rich_text: Vec<RichText>,
},
- /// https://developers.notion.com/reference/page#number-property-values
+ /// <https://developers.notion.com/reference/page#number-property-values>
Number {
id: PropertyId,
number: Number,
},
- /// https://developers.notion.com/reference/page#select-property-values
+ /// <https://developers.notion.com/reference/page#select-property-values>
Select {
id: PropertyId,
select: SelectedValue,
@@ -266,12 +270,12 @@ pub enum PropertyValue {
id: PropertyId,
date: DateValue,
},
- /// https://developers.notion.com/reference/page#formula-property-values
+ /// <https://developers.notion.com/reference/page#formula-property-values>
Formula {
id: PropertyId,
formula: FormulaResultValue,
},
- /// https://developers.notion.com/reference/page#relation-property-values
+ /// <https://developers.notion.com/reference/page#relation-property-values>
Relation {
id: PropertyId,
relation: RelationValue,
diff --git a/src/models/search.rs b/src/models/search.rs
index ffcac1d..aa2f62e 100644
--- a/src/models/search.rs
+++ b/src/models/search.rs
@@ -299,13 +299,24 @@ pub struct DatabaseQuery {
#[derive(Debug, Eq, PartialEq)]
pub enum NotionSearch {
+ /// When supplied, limits which pages are returned by comparing the query to the page title.
Query(String),
+ /// When supplied, sorts the results based on the provided criteria.
+ ///
+ /// Limitation: Currently only a single sort is allowed and is limited to `last_edited_time`
Sort {
timestamp: SortTimestamp,
direction: SortDirection,
},
+ /// When supplied, filters the results based on the provided criteria.
+ ///
+ /// Limitation: Currently the only filter allowed is `object` which will filter by type of object (either page or database)
Filter {
+ /// The name of the property to filter by.
+ /// Currently the only property you can filter by is the `object` type.
property: FilterProperty,
+ /// The value of the property to filter the results by.
+ /// Possible values for object type include `page` or `database`.
value: FilterValue,
},
}
diff --git a/src/models/tests/issue_15.json b/src/models/tests/issue_15.json
new file mode 100644
index 0000000..7ca0615
--- /dev/null
+++ b/src/models/tests/issue_15.json
@@ -0,0 +1,89 @@
+{
+ "object": "list",
+ "results": [
+ {
+ "object": "database",
+ "id": "58be2827-5ca0-4cc4-85a8-ff656911df67",
+ "created_time": "2021-03-07T19:20:00.000Z",
+ "last_edited_time": "2021-07-11T22:04:00.000Z",
+ "title": [
+ {
+ "type": "text",
+ "text": { "content": "Movie Collection", "link": null },
+ "annotations": {
+ "bold": false,
+ "italic": false,
+ "strikethrough": false,
+ "underline": false,
+ "code": false,
+ "color": "default"
+ },
+ "plain_text": "Movie Collection",
+ "href": null
+ }
+ ],
+ "properties": {
+ "Watched": { "id": "<dji", "type": "checkbox", "checkbox": {} },
+ "Cover": { "id": "VWBk", "type": "files", "files": {} },
+ "Type": {
+ "id": "]iu{",
+ "type": "select",
+ "select": {
+ "options": [
+ {
+ "id": "522ab335-108c-4a92-a2d6-0aeee7b946c8",
+ "name": "Blu-Ray",
+ "color": "blue"
+ },
+ {
+ "id": "12f11180-47bd-4c36-abb8-c84c35ade60c",
+ "name": "Digital",
+ "color": "green"
+ }
+ ]
+ }
+ },
+ "Year": {
+ "id": "jwIv",
+ "type": "number",
+ "number": { "format": "number" }
+ },
+ "Director": {
+ "id": "~psh",
+ "type": "select",
+ "select": {
+ "options": [
+ {
+ "id": "d1023a7a-52af-4c2f-aabf-cac75b59e9bd",
+ "name": "Hirozaku Kore-eda",
+ "color": "yellow"
+ },
+ {
+ "id": "45bd4057-eddc-4bf2-be59-a693f4f81f05",
+ "name": "Hayao Miyazaki",
+ "color": "pink"
+ },
+ {
+ "id": "a1a2896b-26f0-410b-8205-fda67c9edb99",
+ "name": "Doug Liman",
+ "color": "orange"
+ },
+ {
+ "id": "f9854b2d-b913-454f-b18c-ce312fa1d9e4",
+ "name": "Steven Soderbergh",
+ "color": "green"
+ }
+ ]
+ }
+ },
+ "Title": { "id": "title", "type": "title", "title": {} }
+ },
+ "parent": {
+ "type": "page_id",
+ "page_id": "2ffcd525-17b1-4606-93ff-e367eade9e66"
+ }
+ }
+ ],
+ "next_cursor": null,
+ "has_more": false
+}
diff --git a/src/models/text.rs b/src/models/text.rs
index f7ea2b6..b960b6d 100644
--- a/src/models/text.rs
+++ b/src/models/text.rs
@@ -25,35 +25,35 @@ pub enum TextColor {
}
/// Rich text annotations
-/// See https://developers.notion.com/reference/rich-text#annotations
+/// See <https://developers.notion.com/reference/rich-text#annotations>
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
-struct Annotations {
- bold: Option<bool>,
- code: Option<bool>,
- color: Option<TextColor>,
- italic: Option<bool>,
- strikethrough: Option<bool>,
- underline: Option<bool>,
+pub struct Annotations {
+ pub bold: Option<bool>,
+ pub code: Option<bool>,
+ pub color: Option<TextColor>,
+ pub italic: Option<bool>,
+ pub strikethrough: Option<bool>,
+ pub underline: Option<bool>,
}
/// Properties common on all rich text objects
-/// See https://developers.notion.com/reference/rich-text#all-rich-text
+/// See <https://developers.notion.com/reference/rich-text#all-rich-text>
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct RichTextCommon {
- plain_text: String,
- href: Option<String>,
- annotations: Option<Annotations>,
+ pub plain_text: String,
+ pub href: Option<String>,
+ pub annotations: Option<Annotations>,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
pub struct Link {
- url: String,
+ pub url: String,
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
pub struct Text {
- content: String,
- link: Option<String>,
+ pub content: String,
+ pub link: Option<String>,
}
/// Rich text objects contain data for displaying formatted text, mentions, and equations.
@@ -64,18 +64,18 @@ pub struct Text {
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
pub enum RichText {
- /// See https://developers.notion.com/reference/rich-text#text-objects
+ /// See <https://developers.notion.com/reference/rich-text#text-objects>
Text {
#[serde(flatten)]
rich_text: RichTextCommon,
text: Text,
},
- /// See https://developers.notion.com/reference/rich-text#mention-objects
+ /// See <https://developers.notion.com/reference/rich-text#mention-objects>
Mention {
#[serde(flatten)]
rich_text: RichTextCommon,
},
- /// See https://developers.notion.com/reference/rich-text#equation-objects
+ /// See <https://developers.notion.com/reference/rich-text#equation-objects>
Equation {
#[serde(flatten)]
rich_text: RichTextCommon,