feat: did further upgrades to help migration to surf

This commit is contained in:
Bram Dingelstad 2024-04-14 21:54:55 +02:00
parent d3ef727207
commit 7b64d525d9
2 changed files with 53 additions and 75 deletions

View file

@ -5,7 +5,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features] [features]
request = [] request = ["surf/h1-client-rustls"]
convert_from_notion = [] convert_from_notion = []
[dependencies] [dependencies]
@ -19,7 +19,4 @@ log = "0.4.20"
regex = "1.7.1" regex = "1.7.1"
serde = { version = "^1.0", features = ["derive"], default-features = false } serde = { version = "^1.0", features = ["derive"], default-features = false }
serde_json = { version = "^1.0", features = ["raw_value"], default-features = false } serde_json = { version = "^1.0", features = ["raw_value"], default-features = false }
surf = { version = "2.3.2", default_features = false, features = ["h1-client-rustls"] } surf = { version = "2.3.2", default_features = false }
[dev-dependencies]
tokio = { version = "1.28.1", features = ["macros"] }

View file

@ -8,6 +8,7 @@ use serde::de::Error as SerdeError;
use serde::{Deserialize, Deserializer, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
use serde_json::json; use serde_json::json;
use serde_json::Value; use serde_json::Value;
use surf::http::StatusCode;
use futures_core::future::BoxFuture; use futures_core::future::BoxFuture;
@ -20,14 +21,15 @@ lazy_static! {
const NOTION_VERSION: &str = "2022-06-28"; const NOTION_VERSION: &str = "2022-06-28";
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
pub type Callback = dyn Fn(&mut surf::RequestBuilder) -> BoxFuture<'_, std::result::Result<surf::Response, surf::Error>> pub type Callback = dyn Fn(surf::RequestBuilder) -> BoxFuture<'static, std::result::Result<surf::Response, surf::Error>>
+ 'static + 'static
+ Send + Send
+ Sync; + Sync;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
Http(surf::Error, Option<Value>), Http(StatusCode, surf::Response),
Surf(surf::Error),
Deserialization(serde_json::Error, Option<Value>), Deserialization(serde_json::Error, Option<Value>),
ChronoParse(chrono::ParseError), ChronoParse(chrono::ParseError),
UnexpectedType, UnexpectedType,
@ -41,7 +43,7 @@ impl std::fmt::Display for Error {
impl From<surf::Error> for Error { impl From<surf::Error> for Error {
fn from(error: surf::Error) -> Self { fn from(error: surf::Error) -> Self {
Error::Http(error, None) Error::Surf(error)
} }
} }
@ -73,6 +75,7 @@ impl From<chrono::ParseError> for Error {
#[cfg(feature = "request")] #[cfg(feature = "request")]
fn get_http_client(notion_api_key: &str) -> surf::Client { fn get_http_client(notion_api_key: &str) -> surf::Client {
log::trace!("Readying HTTP Client");
surf::Config::new() surf::Config::new()
.add_header("Authorization", format!("Bearer {notion_api_key}")) .add_header("Authorization", format!("Bearer {notion_api_key}"))
.expect("to add Authorization header") .expect("to add Authorization header")
@ -114,8 +117,8 @@ impl ClientBuilder {
pub fn custom_request<F>(mut self, callback: F) -> Self pub fn custom_request<F>(mut self, callback: F) -> Self
where where
for<'c> F: Fn( for<'c> F: Fn(
&'c mut surf::RequestBuilder, surf::RequestBuilder,
) -> BoxFuture<'c, std::result::Result<surf::Response, surf::Error>> ) -> BoxFuture<'static, std::result::Result<surf::Response, surf::Error>>
+ 'static + 'static
+ Send + Send
+ Sync, + Sync,
@ -129,17 +132,17 @@ impl ClientBuilder {
pub fn build(self) -> Client { pub fn build(self) -> Client {
let notion_api_key = self.api_key.expect("api_key to be set"); let notion_api_key = self.api_key.expect("api_key to be set");
let request_handler = self.custom_request.unwrap_or(Arc::new( let request_handler =
|request_builder: &mut surf::RequestBuilder| { self.custom_request
Box::pin(async move { .unwrap_or(Arc::new(|request_builder: surf::RequestBuilder| {
// let request = request_builder Box::pin(async move {
// .clone() // let request = request_builder
// .expect("non-stream body request clone to succeed"); // .clone()
// .expect("non-stream body request clone to succeed");
request_builder.await request_builder.await
}) })
}, }));
));
let http_client = Arc::from(get_http_client(&notion_api_key)); let http_client = Arc::from(get_http_client(&notion_api_key));
@ -186,25 +189,20 @@ impl<'a> Client {
self, self,
options: SearchOptions<'b>, options: SearchOptions<'b>,
) -> Result<QueryResponse<T>> { ) -> Result<QueryResponse<T>> {
let mut request = self let request = self
.http_client .http_client
.post("https://api.notion.com/v1/search") .post("https://api.notion.com/v1/search")
.body_json(&options) .body_json(&options)
.expect("to parse JSON for doing `search`"); .expect("to parse JSON for doing `search`");
let mut response = (self.request_handler)(&mut request) let mut response = (self.request_handler)(request)
.await .await
.expect("to request through a request handler"); .expect("to request through a request handler");
Ok(response.body_json().await?) match response.status() {
// TODO: re-implement wrong return from Notion StatusCode::Ok => Ok(response.body_json().await?),
// match response { status => Err(Error::Http(status, response)),
// Ok(_) => Ok(response.body_json().await?), }
// Err(error) => {
// let body = response.body_json::<Value>().await?;
// Err(Error::Http(error, Some(body)))
// }
// }
} }
} }
@ -225,18 +223,13 @@ impl Pages {
page_id = options.page_id page_id = options.page_id
); );
let mut request = self.http_client.get(url); let request = self.http_client.get(url);
let mut response = (self.request_handler)(request).await?;
let mut response = (self.request_handler)(&mut request).await?; match response.status() {
StatusCode::Ok => Ok(response.body_json().await?),
Ok(response.body_json().await?) status => Err(Error::Http(status, response)),
// match response.error_for_status_ref() { }
// Ok(_) => Ok(response.json().await?),
// Err(error) => {
// let body = response.json::<Value>().await?;
// Err(Error::Http(error, Some(body)))
// }
// }
} }
} }
@ -274,19 +267,14 @@ impl BlockChildren {
block_id = options.block_id block_id = options.block_id
); );
let mut request = self.http_client.get(&url); let request = self.http_client.get(&url);
let mut response = (self.request_handler)(&mut request).await?; let mut response = (self.request_handler)(request).await?;
Ok(response.body_json().await?) match response.status() {
StatusCode::Ok => Ok(response.body_json().await?),
// match response.error_for_status_ref() { status => Err(Error::Http(status, response)),
// Ok(_) => Ok(response.json().await?), }
// Err(error) => {
// let body = response.json::<Value>().await?;
// Err(Error::Http(error, Some(body)))
// }
// }
} }
} }
@ -342,23 +330,20 @@ impl Databases {
json json
}; };
if let Some(json) = json { if let Some(ref json) = json {
request = request request = request
.body_json(&json) .body_json(json)
.expect("to parse JSON for start_cursor"); .expect("to parse JSON for start_cursor");
} }
let mut response = (self.request_handler)(&mut request).await?; log::trace!("Querying database with request: {request:#?} and body: {json:#?}");
Ok(response.body_json().await?) let mut response = (self.request_handler)(request).await?;
// match response.error_for_status_ref() { match response.status() {
// Ok(_) => try_to_parse_response(response).await, StatusCode::Ok => Ok(response.body_json().await?),
// Err(error) => { status => Err(Error::Http(status, response)),
// let body = try_to_parse_response::<Value>(response).await?; }
// Err(Error::Http(error, Some(body)))
// }
// }
} }
} }
@ -423,18 +408,14 @@ impl Users {
pub async fn get(&self) -> Result<QueryResponse<User>> { pub async fn get(&self) -> Result<QueryResponse<User>> {
let url = "https://api.notion.com/v1/users".to_owned(); let url = "https://api.notion.com/v1/users".to_owned();
let mut request = self.http_client.get(&url); let request = self.http_client.get(&url);
let mut response = (self.request_handler)(&mut request).await?; let mut response = (self.request_handler)(request).await?;
Ok(response.body_json().await?) match response.status() {
// match response.error_for_status_ref() { StatusCode::Ok => Ok(response.body_json().await?),
// Ok(_) => Ok(response.json().await?), status => Err(Error::Http(status, response)),
// Err(error) => { }
// let body = response.json::<Value>().await?;
// Err(Error::Http(error, Some(body)))
// }
// }
} }
} }
@ -978,7 +959,7 @@ pub struct Relation {
// TODO: Paginate all possible responses // TODO: Paginate all possible responses
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct QueryResponse<T> { pub struct QueryResponse<T> {
pub has_more: bool, pub has_more: Option<bool>,
pub next_cursor: Option<String>, pub next_cursor: Option<String>,
pub results: Vec<T>, pub results: Vec<T>,
} }