Skip to content

Commit

Permalink
Merge pull request #4 from sreedevk/v003
Browse files Browse the repository at this point in the history
Version 0.0.3
  • Loading branch information
sreedevk authored Oct 9, 2022
2 parents 3d1fffa + 6ab545d commit 0d85a69
Show file tree
Hide file tree
Showing 19 changed files with 510 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = ["pocketbase-derive"]

[package]
name = "pocketbase-sdk"
version = "0.0.2"
version = "0.0.3"
edition = "2021"
authors = ["Sreedev Kodichath <sreedev@icloud.com>"]
license = "MIT"
Expand Down
40 changes: 37 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ or add the following to your `Cargo.toml`

```toml
[dependencies]
pocketbase-sdk = "0.0.2"
pocketbase-sdk = "0.0.3"
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0.145", features = ["derive"] }
```
Expand All @@ -21,13 +21,18 @@ serde = { version = "1.0.145", features = ["derive"] }
use pocketbase_sdk::client::Client;
use pocketbase_sdk::user::UserTypes;
use pocketbase_sdk::records::Recordable;
use pocketbase_sdk::records::operations::list;
use pocketbase_sdk::records::operations::{
list, view, delete, create
};

#[derive(Recordable)]
struct Post {
id: String,
title: String,
content: String,
published_at: String
created: String,
updated: String,
author: String,
}

#[tokio::main]
Expand All @@ -41,6 +46,31 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
).await;
assert!(auth.is_ok())

/* create record */
let record = Post {
title: "Sample title".to_string(),
content: "Sample Content".to_string(),
author: client.user.unwrap().token,
created: "".to_string,
updated: "".to_string
};

let repsonse = create::record::<Post>("posts", &post, &client).await.unwrap();
match repsonse {
create::CreateResponse::SuccessResponse(res) => {
assert_eq!(res.title, String::from("Sample title"))
},
create::CreateResponse::FailureResponse(_err) => panic!("Failed!")
}

/* view record */
let repsonse = view::record::<Post>("posts", "9bbl183t7ioqrea", &client).await.unwrap();
match repsonse {
view::ViewResponse::SuccessResponse(res) => assert_eq!(res.id, "9bbl183t7ioqrea"),
view::ViewResponse::ErrorResponse(_err) => panic!("Failed!")
}

/* list paginated records */
let response = list::records::<Post>("posts", &client).await.unwrap();
match response {
ListResponse::SuccessResponse(paginated_record_list) => {
Expand All @@ -49,6 +79,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
ListResponse::ErrorResponse(_e) => panic!("could not retrieve resource.")
}

/* delete a record */
let response = delete::record("posts", "9bbl183t7ioqrea", &client).await;
assert!(response.is_ok());

Ok(())
}

Expand Down
8 changes: 4 additions & 4 deletions src/client/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct SuccessAuthResponse {

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct FailuredAuthResponse {
pub struct FailureAuthResponse {
pub code: String,
pub message: String,
pub data: HashMap<String, String>
Expand All @@ -38,7 +38,7 @@ pub struct FailuredAuthResponse {
#[serde(rename_all = "camelCase", untagged)]
pub enum AuthResponse {
SuccessAuthResponse(SuccessAuthResponse),
FailuredAuthResponse(FailuredAuthResponse)
FailureAuthResponse(FailureAuthResponse)
}

impl Client {
Expand Down Expand Up @@ -83,7 +83,7 @@ impl Client {

Ok(())
},
AuthResponse::FailuredAuthResponse(_response) => {
AuthResponse::FailureAuthResponse(_response) => {
Err(Box::new(AuthenticationError))
}
}
Expand Down Expand Up @@ -118,7 +118,7 @@ impl Client {

Ok(())
},
AuthResponse::FailuredAuthResponse(_response) => {
AuthResponse::FailureAuthResponse(_response) => {
Err(Box::new(AuthenticationError))
}
}
Expand Down
102 changes: 99 additions & 3 deletions src/client/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,39 @@ use std::error;
use crate::user::UserTypes;

impl Client {
pub async fn get(&self, path: String) ->
pub async fn get(&self, path: String, params: Option<&[(&str, &str)]>) ->
Result<Response, Box<dyn error::Error>> {
match self.base_url.join(path.as_str()) {
Ok(request_url) => {
match reqwest::get(request_url).await {
let req_client = reqwest::Client::new();
let request = req_client.get(request_url);
let opts_attached = match params {
Some(args) => request.query(args),
None => request
};

let authed_req = match &self.user {
Some(user) => {
match &user.usertype {
UserTypes::User => {
opts_attached.header(
AUTHORIZATION,
format!("User {}", user.token)
)
},
UserTypes::Admin => {
opts_attached.header(
AUTHORIZATION,
format!("Admin {}", user.token)
)

}
}
}
None => opts_attached
};

match authed_req.send().await {
Ok(response) => Ok(response),
Err(e) => Err(Box::new(e) as Box<dyn error::Error>)
}
Expand Down Expand Up @@ -75,7 +103,75 @@ impl Client {
.header(header::CONTENT_TYPE, "application/json")
.body(serde_json::to_string(body).unwrap());

match req.send().await {
let authed_req = match &self.user {
Some(user) => {
match &user.usertype {
UserTypes::User => {
req.header(
AUTHORIZATION,
format!("User {}", user.token)
)
},
UserTypes::Admin => {
req.header(
AUTHORIZATION,
format!("Admin {}", user.token)
)

}
}
}
None => req
};

match authed_req.send().await {
Ok(response) => Ok(response),
Err(e) => Err(Box::new(e) as Box<dyn error::Error>)
}
},
Err(e) => Err(Box::new(e) as Box<dyn error::Error>)
}
}

pub async fn delete(
&self,
path: String,
params: Option<&[(&str, &str)]>
) -> Result<Response, Box<dyn error::Error>> {
match self.base_url.join(path.as_str()) {
Ok(request_url) => {
let req_client = reqwest::Client::new();
let req = req_client
.patch(request_url)
.header(header::CONTENT_TYPE, "application/json");

let opts_attached = match params {
Some(args) => req.query(args),
None => req
};

let authed_req = match &self.user {
Some(user) => {
match &user.usertype {
UserTypes::User => {
opts_attached.header(
AUTHORIZATION,
format!("User {}", user.token)
)
},
UserTypes::Admin => {
opts_attached.header(
AUTHORIZATION,
format!("Admin {}", user.token)
)

}
}
}
None => opts_attached
};

match authed_req.send().await {
Ok(response) => Ok(response),
Err(e) => Err(Box::new(e) as Box<dyn error::Error>)
}
Expand Down
7 changes: 7 additions & 0 deletions src/records/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
pub mod operations;

pub use operations::create;
pub use operations::list;
pub use operations::view;
pub use operations::delete;
pub use operations::update;

pub trait Recordable {}
pub trait Changeset {}
31 changes: 31 additions & 0 deletions src/records/operations/create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::client::Client;
use serde::{Serialize, Deserialize};
use std::error::Error;
use serde::de::DeserializeOwned;

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct FailureResponse {
code: String,
message: String
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub enum CreateResponse<T> {
SuccessResponse(T),
FailureResponse(FailureResponse)
}

pub async fn record<T: Serialize + DeserializeOwned>(collection: &str, changeset: &T, client: &Client) -> Result<CreateResponse<T>, Box<dyn Error>> {
let url = format!("collections/{}/records", collection);
match client.post::<T>(url, &changeset).await {
Ok(response) => {
match response.json::<T>().await {
Ok(parsed) => Ok(CreateResponse::SuccessResponse(parsed)),
Err(e) => Err(Box::new(e) as Box<dyn Error>)
}
},
Err(e) => Err(e)
}
}
38 changes: 38 additions & 0 deletions src/records/operations/delete.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::collections::HashMap;
use std::error::Error;

use serde::{Serialize, Deserialize};

use crate::client::Client;

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct SuccessResponse {}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct FailureResponse {
code: String,
message: String,
data: HashMap<String, String>
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", untagged)]
enum DeleteResponse {
SuccessResponse(SuccessResponse),
FailureResponse(FailureResponse)
}

pub async fn record(collection: &str, id: &str, client: &Client) -> Result<(), Box<dyn Error>> {
let url = format!("/api/collections/{}/records/{}", collection, id);
match client.delete(url, None).await {
Ok(resp) => {
match resp.json::<DeleteResponse>().await {
Ok(_) => Ok(()),
Err(e) => Err(Box::new(e) as Box<dyn Error>)
}
},
Err(err) => Err(err)
}
}
3 changes: 2 additions & 1 deletion src/records/operations/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ pub enum ListResponse<T> {

pub async fn records<T: Recordable + DeserializeOwned>(collection: &str, client: &Client) -> Result<ListResponse<T>, Box<dyn Error>> {
let list_response = client.get(
format!("collections/{}/records", collection)
format!("collections/{}/records", collection),
None
).await;

match list_response {
Expand Down
3 changes: 3 additions & 0 deletions src/records/operations/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
pub mod list;
pub mod create;
pub mod view;
pub mod delete;
pub mod update;
31 changes: 31 additions & 0 deletions src/records/operations/update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::client::Client;
use serde::{Serialize, Deserialize};
use std::error::Error;
use serde::de::DeserializeOwned;

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct FailureResponse {
code: String,
message: String
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub enum CreateResponse<T> {
SuccessResponse(T),
FailureResponse(FailureResponse)
}

pub async fn record<T: Serialize + DeserializeOwned>(collection: &str, id: &str, changeset: &T, client: &Client) -> Result<CreateResponse<T>, Box<dyn Error>> {
let url = format!("collections/{}/records/{}", collection, id);
match client.patch::<T>(url, &changeset).await {
Ok(response) => {
match response.json::<T>().await {
Ok(parsed) => Ok(CreateResponse::SuccessResponse(parsed)),
Err(e) => Err(Box::new(e) as Box<dyn Error>)
}
},
Err(e) => Err(e)
}
}
Loading

0 comments on commit 0d85a69

Please sign in to comment.