aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs106
1 files changed, 76 insertions, 30 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 7fbaa15..19d79ee 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,49 +1,77 @@
use crate::models::search::SearchRequest;
-use crate::models::{Database, ListResponse};
+use crate::models::{Database, DatabaseId, ListResponse};
+use reqwest::header::{HeaderMap, HeaderValue};
+use reqwest::{header, Client, ClientBuilder, RequestBuilder};
+use serde::de::DeserializeOwned;
mod models;
+const NOTION_API_VERSION: &'static str = "2021-05-13";
+
+// todo: replace with proper snafu error
+pub type NotionApiClientError = Box<dyn std::error::Error>;
+
struct NotionApi {
- token: String,
+ client: Client,
}
impl NotionApi {
- /// This method is apparently deprecated
+ pub fn new(api_token: String) -> Result<Self, NotionApiClientError> {
+ let mut headers = HeaderMap::new();
+ headers.insert(
+ "Notion-Version",
+ HeaderValue::from_static(NOTION_API_VERSION),
+ );
+
+ let mut auth_value = HeaderValue::from_str(&format!("Bearer {}", api_token))?;
+ auth_value.set_sensitive(true);
+ headers.insert(header::AUTHORIZATION, auth_value);
+
+ let client = ClientBuilder::new().default_headers(headers).build()?;
+
+ Ok(Self { client })
+ }
+
+ async fn make_json_request<T>(request: RequestBuilder) -> Result<T, NotionApiClientError>
+ where
+ T: DeserializeOwned,
+ {
+ let json = request.send().await?.text().await?;
+ dbg!(serde_json::from_str::<serde_json::Value>(&json)?);
+ let result = serde_json::from_str(&json)?;
+ Ok(result)
+ }
+
+ /// This method is apparently deprecated/"not recommended"
pub async fn list_databases(
&self,
) -> Result<ListResponse<Database>, Box<dyn std::error::Error>> {
- let client = reqwest::ClientBuilder::new().build()?;
- let json = client
- .get("https://api.notion.com/v1/databases")
- .bearer_auth(self.token.clone())
- .send()
- .await?
- .text()
- .await?;
- dbg!(&json);
- let result = serde_json::from_str(&json)?;
+ let builder = self.client.get("https://api.notion.com/v1/databases");
- Ok(result)
+ Ok(NotionApi::make_json_request(builder).await?)
}
pub async fn search<T: Into<SearchRequest>>(
&self,
query: T,
) -> Result<ListResponse<Database>, Box<dyn std::error::Error>> {
- let client = reqwest::ClientBuilder::new().build()?;
- let json = client
- .post("https://api.notion.com/v1/search")
- .bearer_auth(self.token.clone())
- .json(&query.into())
- .send()
- .await?
- .text()
- .await?;
-
- dbg!(serde_json::from_str::<serde_json::Value>(&json)?);
- let result = serde_json::from_str(&json)?;
+ Ok(NotionApi::make_json_request(
+ self.client
+ .post("https://api.notion.com/v1/search")
+ .json(&query.into()),
+ )
+ .await?)
+ }
- Ok(result)
+ pub async fn get_database<T: AsRef<DatabaseId>>(
+ &self,
+ database_id: T,
+ ) -> Result<Database, Box<dyn std::error::Error>> {
+ Ok(NotionApi::make_json_request(self.client.get(format!(
+ "https://api.notion.com/v1/databases/{}",
+ database_id.as_ref().id()
+ )))
+ .await?)
}
}
@@ -54,9 +82,7 @@ mod tests {
const TEST_TOKEN: &'static str = include_str!(".api_token");
fn test_client() -> NotionApi {
- NotionApi {
- token: TEST_TOKEN.trim().to_string(),
- }
+ NotionApi::new(TEST_TOKEN.trim().to_string()).unwrap()
}
#[tokio::test]
@@ -82,4 +108,24 @@ mod tests {
Ok(())
}
+
+ #[tokio::test]
+ async fn get_database() -> Result<(), Box<dyn std::error::Error>> {
+ let api = test_client();
+
+ let response = api
+ .search(NotionSearch::Filter {
+ value: FilterValue::Database,
+ property: FilterProperty::Object,
+ })
+ .await?;
+
+ let db = response.results()[0].clone();
+
+ let db_result = api.get_database(&db).await?;
+
+ assert_eq!(db, db_result);
+
+ Ok(())
+ }
}