wip: started replacing reqwest with surf
This commit is contained in:
parent
2760c7c24f
commit
83cc5e85fc
|
@ -9,6 +9,7 @@ request = []
|
||||||
convert_from_notion = []
|
convert_from_notion = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-std = "1.12.0"
|
||||||
async-trait = "0.1.68"
|
async-trait = "0.1.68"
|
||||||
base64 = "0.21.0"
|
base64 = "0.21.0"
|
||||||
chrono = "0.4.31"
|
chrono = "0.4.31"
|
||||||
|
@ -16,9 +17,9 @@ futures-core = "0.3.28"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
regex = "1.7.1"
|
regex = "1.7.1"
|
||||||
reqwest = { version = "0.11.14", features = ["json"] }
|
|
||||||
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 = "2.3.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1.28.1", features = ["macros"] }
|
tokio = { version = "1.28.1", features = ["macros"] }
|
||||||
|
|
191
src/lib.rs
191
src/lib.rs
|
@ -4,8 +4,6 @@ use std::sync::Arc;
|
||||||
use chrono::{DateTime, NaiveTime, Utc};
|
use chrono::{DateTime, NaiveTime, Utc};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
#[cfg(feature = "request")]
|
|
||||||
use reqwest::header::{HeaderMap, HeaderValue};
|
|
||||||
use serde::de::Error as SerdeError;
|
use serde::de::Error as SerdeError;
|
||||||
use serde::{Deserialize, Deserializer, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
@ -22,18 +20,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(
|
pub type Callback = dyn Fn(&mut surf::RequestBuilder) -> BoxFuture<'_, std::result::Result<surf::Response, surf::Error>>
|
||||||
&mut reqwest::RequestBuilder,
|
|
||||||
) -> BoxFuture<'_, std::result::Result<reqwest::Response, reqwest::Error>>
|
|
||||||
+ 'static
|
+ 'static
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync;
|
+ Sync;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Http(reqwest::Error, Option<Value>),
|
Http(surf::Error, Option<Value>),
|
||||||
Deserialization(serde_json::Error, Option<Value>),
|
Deserialization(serde_json::Error, Option<Value>),
|
||||||
Header(reqwest::header::InvalidHeaderValue),
|
|
||||||
ChronoParse(chrono::ParseError),
|
ChronoParse(chrono::ParseError),
|
||||||
UnexpectedType,
|
UnexpectedType,
|
||||||
}
|
}
|
||||||
|
@ -44,18 +39,12 @@ impl std::fmt::Display for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<reqwest::Error> for Error {
|
impl From<surf::Error> for Error {
|
||||||
fn from(error: reqwest::Error) -> Self {
|
fn from(error: surf::Error) -> Self {
|
||||||
Error::Http(error, None)
|
Error::Http(error, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<reqwest::header::InvalidHeaderValue> for Error {
|
|
||||||
fn from(error: reqwest::header::InvalidHeaderValue) -> Self {
|
|
||||||
Error::Header(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<serde_json::Error> for Error {
|
impl From<serde_json::Error> for Error {
|
||||||
fn from(error: serde_json::Error) -> Self {
|
fn from(error: serde_json::Error) -> Self {
|
||||||
Error::Deserialization(error, None)
|
Error::Deserialization(error, None)
|
||||||
|
@ -68,37 +57,30 @@ impl From<chrono::ParseError> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn try_to_parse_response<T: std::fmt::Debug + for<'de> serde::Deserialize<'de>>(
|
// async fn try_to_parse_response<T: std::fmt::Debug + for<'de> serde::Deserialize<'de>>(
|
||||||
response: reqwest::Response,
|
// mut response: surf::Response,
|
||||||
) -> Result<T> {
|
// ) -> Result<T> {
|
||||||
let text = response.text().await?;
|
// let text = response.body_string().await?;
|
||||||
|
|
||||||
match serde_json::from_str::<T>(&text) {
|
// match serde_json::from_str::<T>(&text) {
|
||||||
Ok(value) => Ok(value),
|
// Ok(value) => Ok(value),
|
||||||
Err(error) => match serde_json::from_str::<Value>(&text) {
|
// Err(error) => match serde_json::from_str::<Value>(&text) {
|
||||||
Ok(body) => Err(Error::Deserialization(error, Some(body))),
|
// Ok(body) => Err(Error::Deserialization(error, Some(body))),
|
||||||
_ => Err(Error::Deserialization(error, Some(Value::String(text)))),
|
// _ => Err(Error::Deserialization(error, Some(Value::String(text)))),
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[cfg(feature = "request")]
|
#[cfg(feature = "request")]
|
||||||
fn get_http_client(notion_api_key: &str) -> reqwest::Client {
|
fn get_http_client(notion_api_key: &str) -> surf::Client {
|
||||||
let mut headers = HeaderMap::new();
|
surf::Config::new()
|
||||||
headers.insert(
|
.add_header("Authorization", format!("Bearer {notion_api_key}"))
|
||||||
"Authorization",
|
.unwrap()
|
||||||
HeaderValue::from_str(&format!("Bearer {notion_api_key}"))
|
.add_header("Notion-Version", NOTION_VERSION)
|
||||||
.expect("bearer token to be parsed into a header"),
|
.unwrap()
|
||||||
);
|
.add_header("Content-Type", "application/json")
|
||||||
headers.insert(
|
.unwrap()
|
||||||
"Notion-Version",
|
.try_into()
|
||||||
HeaderValue::from_str(NOTION_VERSION).expect("notion version to be parsed into a header"),
|
|
||||||
);
|
|
||||||
headers.insert("Content-Type", HeaderValue::from_static("application/json"));
|
|
||||||
|
|
||||||
reqwest::ClientBuilder::new()
|
|
||||||
.default_headers(headers)
|
|
||||||
.build()
|
|
||||||
.expect("to build a valid client out of notion_api_key")
|
.expect("to build a valid client out of notion_api_key")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +114,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 reqwest::RequestBuilder,
|
&'c mut surf::RequestBuilder,
|
||||||
) -> BoxFuture<'c, std::result::Result<reqwest::Response, reqwest::Error>>
|
) -> BoxFuture<'c, std::result::Result<surf::Response, surf::Error>>
|
||||||
+ 'static
|
+ 'static
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync,
|
+ Sync,
|
||||||
|
@ -148,13 +130,13 @@ impl ClientBuilder {
|
||||||
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 = self.custom_request.unwrap_or(Arc::new(
|
||||||
|request_builder: &mut reqwest::RequestBuilder| {
|
|request_builder: &mut surf::RequestBuilder| {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let request = request_builder
|
// let request = request_builder
|
||||||
.try_clone()
|
// .clone()
|
||||||
.expect("non-stream body request clone to succeed");
|
// .expect("non-stream body request clone to succeed");
|
||||||
|
|
||||||
request.send().await
|
request_builder.await
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
@ -186,7 +168,7 @@ impl ClientBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
http_client: Arc<reqwest::Client>,
|
http_client: Arc<surf::Client>,
|
||||||
request_handler: Arc<Callback>,
|
request_handler: Arc<Callback>,
|
||||||
|
|
||||||
pub pages: Pages,
|
pub pages: Pages,
|
||||||
|
@ -207,17 +189,20 @@ impl<'a> Client {
|
||||||
let mut request = self
|
let mut request = self
|
||||||
.http_client
|
.http_client
|
||||||
.post("https://api.notion.com/v1/search")
|
.post("https://api.notion.com/v1/search")
|
||||||
.json(&options);
|
.body_json(&options)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let response = (self.request_handler)(&mut request).await?;
|
let mut response = (self.request_handler)(&mut request).await.unwrap();
|
||||||
|
|
||||||
match response.error_for_status_ref() {
|
Ok(response.body_json().await?)
|
||||||
Ok(_) => Ok(response.json().await?),
|
// TODO: re-implement wrong return from Notion
|
||||||
Err(error) => {
|
// match response {
|
||||||
let body = response.json::<Value>().await?;
|
// Ok(_) => Ok(response.body_json().await?),
|
||||||
Err(Error::Http(error, Some(body)))
|
// Err(error) => {
|
||||||
}
|
// let body = response.body_json::<Value>().await?;
|
||||||
}
|
// Err(Error::Http(error, Some(body)))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +212,7 @@ pub struct PageOptions<'a> {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Pages {
|
pub struct Pages {
|
||||||
http_client: Arc<reqwest::Client>,
|
http_client: Arc<surf::Client>,
|
||||||
request_handler: Arc<Callback>,
|
request_handler: Arc<Callback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,21 +225,22 @@ impl Pages {
|
||||||
|
|
||||||
let mut request = self.http_client.get(url);
|
let mut request = self.http_client.get(url);
|
||||||
|
|
||||||
let response = (self.request_handler)(&mut request).await?;
|
let mut response = (self.request_handler)(&mut request).await?;
|
||||||
|
|
||||||
match response.error_for_status_ref() {
|
Ok(response.body_json().await?)
|
||||||
Ok(_) => Ok(response.json().await?),
|
// match response.error_for_status_ref() {
|
||||||
Err(error) => {
|
// Ok(_) => Ok(response.json().await?),
|
||||||
let body = response.json::<Value>().await?;
|
// Err(error) => {
|
||||||
Err(Error::Http(error, Some(body)))
|
// let body = response.json::<Value>().await?;
|
||||||
}
|
// Err(Error::Http(error, Some(body)))
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Blocks {
|
pub struct Blocks {
|
||||||
http_client: Arc<reqwest::Client>,
|
http_client: Arc<surf::Client>,
|
||||||
request_handler: Arc<Callback>,
|
request_handler: Arc<Callback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +254,7 @@ impl Blocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BlockChildren {
|
pub struct BlockChildren {
|
||||||
http_client: Arc<reqwest::Client>,
|
http_client: Arc<surf::Client>,
|
||||||
request_handler: Arc<Callback>,
|
request_handler: Arc<Callback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,21 +274,23 @@ impl BlockChildren {
|
||||||
|
|
||||||
let mut request = self.http_client.get(&url);
|
let mut request = self.http_client.get(&url);
|
||||||
|
|
||||||
let response = (self.request_handler)(&mut request).await?;
|
let mut response = (self.request_handler)(&mut request).await?;
|
||||||
|
|
||||||
match response.error_for_status_ref() {
|
Ok(response.body_json().await?)
|
||||||
Ok(_) => Ok(response.json().await?),
|
|
||||||
Err(error) => {
|
// match response.error_for_status_ref() {
|
||||||
let body = response.json::<Value>().await?;
|
// Ok(_) => Ok(response.json().await?),
|
||||||
Err(Error::Http(error, Some(body)))
|
// Err(error) => {
|
||||||
}
|
// let body = response.json::<Value>().await?;
|
||||||
}
|
// Err(Error::Http(error, Some(body)))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Databases {
|
pub struct Databases {
|
||||||
http_client: Arc<reqwest::Client>,
|
http_client: Arc<surf::Client>,
|
||||||
request_handler: Arc<Callback>,
|
request_handler: Arc<Callback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,18 +341,20 @@ impl Databases {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(json) = json {
|
if let Some(json) = json {
|
||||||
request = request.json(&json);
|
request = request.body_json(&json).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = (self.request_handler)(&mut request).await?;
|
let mut response = (self.request_handler)(&mut request).await?;
|
||||||
|
|
||||||
match response.error_for_status_ref() {
|
Ok(response.body_json().await?)
|
||||||
Ok(_) => try_to_parse_response(response).await,
|
|
||||||
Err(error) => {
|
// match response.error_for_status_ref() {
|
||||||
let body = try_to_parse_response::<Value>(response).await?;
|
// Ok(_) => try_to_parse_response(response).await,
|
||||||
Err(Error::Http(error, Some(body)))
|
// Err(error) => {
|
||||||
}
|
// let body = try_to_parse_response::<Value>(response).await?;
|
||||||
}
|
// Err(Error::Http(error, Some(body)))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +362,7 @@ impl Databases {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[tokio::test]
|
#[async_std::test]
|
||||||
async fn check_database_query() {
|
async fn check_database_query() {
|
||||||
let databases = Client::new()
|
let databases = Client::new()
|
||||||
.api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud")
|
.api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud")
|
||||||
|
@ -394,7 +384,7 @@ mod tests {
|
||||||
println!("{databases:#?}");
|
println!("{databases:#?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[async_std::test]
|
||||||
async fn test_blocks() {
|
async fn test_blocks() {
|
||||||
let blocks = Client::new()
|
let blocks = Client::new()
|
||||||
.api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud")
|
.api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud")
|
||||||
|
@ -421,7 +411,7 @@ pub struct DatabaseQueryOptions<'a> {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Users {
|
pub struct Users {
|
||||||
http_client: Arc<reqwest::Client>,
|
http_client: Arc<surf::Client>,
|
||||||
request_handler: Arc<Callback>,
|
request_handler: Arc<Callback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,15 +421,16 @@ impl Users {
|
||||||
|
|
||||||
let mut request = self.http_client.get(&url);
|
let mut request = self.http_client.get(&url);
|
||||||
|
|
||||||
let response = (self.request_handler)(&mut request).await?;
|
let mut response = (self.request_handler)(&mut request).await?;
|
||||||
|
|
||||||
match response.error_for_status_ref() {
|
Ok(response.body_json().await?)
|
||||||
Ok(_) => Ok(response.json().await?),
|
// match response.error_for_status_ref() {
|
||||||
Err(error) => {
|
// Ok(_) => Ok(response.json().await?),
|
||||||
let body = response.json::<Value>().await?;
|
// Err(error) => {
|
||||||
Err(Error::Http(error, Some(body)))
|
// let body = response.json::<Value>().await?;
|
||||||
}
|
// Err(Error::Http(error, Some(body)))
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue