feat: removed all Arc's for better memory usage and less dangling pointers

This commit is contained in:
Bram Dingelstad 2025-02-21 15:38:58 +01:00
parent 16fd39e8c0
commit 50ccd6b339

View file

@ -1,5 +1,4 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc;
use chrono::{DateTime, NaiveTime, Utc}; use chrono::{DateTime, NaiveTime, Utc};
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -104,7 +103,7 @@ pub struct SearchOptions<'a> {
#[derive(Default)] #[derive(Default)]
pub struct ClientBuilder { pub struct ClientBuilder {
api_key: Option<String>, api_key: Option<String>,
custom_request: Option<Arc<Callback>>, custom_request: Option<Box<Callback>>,
} }
impl ClientBuilder { impl ClientBuilder {
@ -123,7 +122,7 @@ impl ClientBuilder {
+ Send + Send
+ Sync, + Sync,
{ {
self.custom_request = Some(Arc::new(callback)); self.custom_request = Some(Box::new(callback));
self self
} }
@ -132,46 +131,18 @@ 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(|request_builder: surf::RequestBuilder| {
Box::pin(request_builder)
}));
let http_client = Arc::from(get_http_client(&notion_api_key));
Client { Client {
http_client: http_client.clone(), http_client: get_http_client(&notion_api_key),
request_handler: request_handler.clone(), request_handler: self.custom_request.unwrap_or(Box::new(
|request_builder: surf::RequestBuilder| Box::pin(request_builder),
pages: Pages { )),
http_client: http_client.clone(),
request_handler: request_handler.clone(),
},
blocks: Blocks {
http_client: http_client.clone(),
request_handler: request_handler.clone(),
},
databases: Databases {
http_client: http_client.clone(),
request_handler: request_handler.clone(),
},
users: Users {
http_client: http_client.clone(),
request_handler: request_handler.clone(),
},
} }
} }
} }
pub struct Client { pub struct Client {
http_client: Arc<surf::Client>, http_client: surf::Client,
request_handler: Arc<Callback>, request_handler: Box<Callback>,
pub pages: Pages,
pub blocks: Blocks,
pub databases: Databases,
pub users: Users,
} }
impl<'a> Client { impl<'a> Client {
@ -199,19 +170,46 @@ impl<'a> Client {
status => Err(Error::Http(status, response)), status => Err(Error::Http(status, response)),
} }
} }
pub fn pages(&'a self) -> Pages<'a> {
Pages {
http_client: &self.http_client,
request_handler: &self.request_handler,
}
}
pub fn blocks(&'a self) -> Blocks<'a> {
Blocks {
http_client: &self.http_client,
request_handler: &self.request_handler,
}
}
pub fn databases(&'a self) -> Databases<'a> {
Databases {
http_client: &self.http_client,
request_handler: &self.request_handler,
}
}
pub fn users(&'a self) -> Users<'a> {
Users {
http_client: &self.http_client,
request_handler: &self.request_handler,
}
}
} }
pub struct PageOptions<'a> { pub struct PageOptions<'a> {
pub page_id: &'a str, pub page_id: &'a str,
} }
#[derive(Clone)] pub struct Pages<'a> {
pub struct Pages { http_client: &'a surf::Client,
http_client: Arc<surf::Client>, request_handler: &'a Box<Callback>,
request_handler: Arc<Callback>,
} }
impl Pages { impl Pages<'_> {
pub async fn retrieve(&self, options: PageOptions<'_>) -> Result<Page> { pub async fn retrieve(&self, options: PageOptions<'_>) -> Result<Page> {
let url = format!( let url = format!(
"https://api.notion.com/v1/pages/{page_id}", "https://api.notion.com/v1/pages/{page_id}",
@ -228,31 +226,30 @@ impl Pages {
} }
} }
#[derive(Clone)] pub struct Blocks<'a> {
pub struct Blocks { http_client: &'a surf::Client,
http_client: Arc<surf::Client>, request_handler: &'a Box<Callback>,
request_handler: Arc<Callback>,
} }
impl Blocks { impl Blocks<'_> {
pub fn children(&self) -> BlockChildren { pub fn children(&self) -> BlockChildren {
BlockChildren { BlockChildren {
http_client: self.http_client.clone(), http_client: self.http_client,
request_handler: self.request_handler.clone(), request_handler: self.request_handler,
} }
} }
} }
pub struct BlockChildren { pub struct BlockChildren<'a> {
http_client: Arc<surf::Client>, http_client: &'a surf::Client,
request_handler: Arc<Callback>, request_handler: &'a Box<Callback>,
} }
pub struct BlockChildrenListOptions<'a> { pub struct BlockChildrenListOptions<'a> {
pub block_id: &'a str, pub block_id: &'a str,
} }
impl BlockChildren { impl BlockChildren<'_> {
pub async fn list( pub async fn list(
&self, &self,
options: BlockChildrenListOptions<'_>, options: BlockChildrenListOptions<'_>,
@ -273,13 +270,12 @@ impl BlockChildren {
} }
} }
#[derive(Clone)] pub struct Databases<'a> {
pub struct Databases { http_client: &'a surf::Client,
http_client: Arc<surf::Client>, request_handler: &'a Box<Callback>,
request_handler: Arc<Callback>,
} }
impl Databases { impl Databases<'_> {
pub async fn query<'a>( pub async fn query<'a>(
&self, &self,
options: DatabaseQueryOptions<'a>, options: DatabaseQueryOptions<'a>,
@ -344,7 +340,7 @@ mod tests {
#[async_std::test] #[async_std::test]
async fn check_database_query() { async fn check_database_query() {
let databases = Client::new() let _ = Client::new()
.api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud") .api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud")
.build() .build()
.search::<Database>(SearchOptions { .search::<Database>(SearchOptions {
@ -364,10 +360,10 @@ mod tests {
#[async_std::test] #[async_std::test]
async fn test_blocks() { async fn test_blocks() {
let blocks = Client::new() let _ = Client::new()
.api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud") .api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud")
.build() .build()
.blocks .blocks()
.children() .children()
.list(BlockChildrenListOptions { .list(BlockChildrenListOptions {
block_id: "0d253ab0f751443aafb9bcec14012897", block_id: "0d253ab0f751443aafb9bcec14012897",
@ -385,13 +381,12 @@ pub struct DatabaseQueryOptions<'a> {
pub start_cursor: Option<String>, pub start_cursor: Option<String>,
} }
#[derive(Clone)] pub struct Users<'a> {
pub struct Users { http_client: &'a surf::Client,
http_client: Arc<surf::Client>, request_handler: &'a Box<Callback>,
request_handler: Arc<Callback>,
} }
impl Users { 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();