Skip to content

Commit

Permalink
Merge pull request #36 from emreyalvac/custom-key-implementation
Browse files Browse the repository at this point in the history
Custom Key Implementation
  • Loading branch information
emreyalvac authored Nov 20, 2024
2 parents 4a9364e + 8435c78 commit bf352f7
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 88 deletions.
24 changes: 12 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "firebase-rs"
edition = "2021"
version = "2.1.2"
version = "2.2.0"
description = "Rust based Firebase library"
readme = "README.md"
repository = "https://github.com/emreyalvac/firebase-rs"
documentation = "https://docs.rs/firebase-rs/2.1.2/firebase_rs/"
documentation = "https://docs.rs/firebase-rs/2.2.0/firebase_rs/"
license = "MIT"
authors = ["Emre YALVAÇ <[email protected]>"]
exclude = ["examples/*", "tests/*"]
Expand All @@ -21,4 +21,4 @@ eventsource-client = "0.10.2"
futures-util = "0.3.28"

[dev-dependencies]
tokio = { version = "1.29.1", features = ["rt", "macros", "rt-multi-thread"] }
tokio = { version = "1.29.1", features = ["rt", "macros", "rt-multi-thread"] }
41 changes: 37 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Rust based Firebase library.

# Full Documentation

[Documentation](https://docs.rs/firebase-rs/2.1.2/firebase_rs/)
[Documentation](https://docs.rs/firebase-rs/2.2.0/firebase_rs/)

# Features

Expand Down Expand Up @@ -76,7 +76,7 @@ struct User {
}

let firebase = Firebase::new("https://myfirebase.firebaseio.com").unwrap().at("users");
let user = firebase.get::<HashMap<String, User> > ().await;
let user = firebase.get::<HashMap<String, User>> ().await;
````

#### Read data with generic type (Single record)
Expand All @@ -93,6 +93,29 @@ let user = firebase.get::<User>().await;

---

### Set Data with Custom Key

````rust
#[derive(Serialize, Deserialize, Debug)]
struct User {
name: String
}

let user = User { name: String::default () };
let mut firebase = Firebase::new("https://myfirebase.firebaseio.com").unwrap().at("users");
firebase.set_with_key("myKey", &user).await;
````
_Output_
```json
{
"users": {
"myKey": {
"name": ""
}
}
}
```

### Set Data

````rust
Expand All @@ -103,8 +126,18 @@ struct User {

let user = User { name: String::default () };
let firebase = Firebase::new("https://myfirebase.firebaseio.com").unwrap().at("users");
firebase.set( & user).await;
firebase.set(&user).await;
````
_Output_
```json
{
"users": {
"-OC9mYIUIdY3JygkmsFQ": {
"name": ""
}
}
}
```

---

Expand All @@ -118,7 +151,7 @@ struct User {

let user = User { name: String::default () };
let firebase = Firebase::new("https://myfirebase.firebaseio.com").unwrap().at("users").at("USER_ID");
firebase.update( & user).await;
firebase.update( &user).await;
````

---
Expand Down
3 changes: 2 additions & 1 deletion src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ pub const SHALLOW: &str = "shallow";
pub const FORMAT: &str = "format";
pub const EXPORT: &str = "export";

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum Method {
GET,
POST,
DELETE,
PATCH,
PUT,
}

#[derive(Debug)]
Expand Down
141 changes: 73 additions & 68 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,25 +115,34 @@ impl Firebase {
/// let firebase = Firebase::new("https://myfirebase.firebaseio.com").unwrap().at("users").at("USER_ID").at("f69111a8a5258c15286d3d0bd4688c55");
/// ```
pub fn at(&self, path: &str) -> Self {
let mut new_path = String::default();
let uri = self.build_uri(path);

let paths = self.uri.path_segments().map(|p| p.collect::<Vec<_>>());
for mut path in paths.unwrap() {
if path.find(".json").is_some() {
path = path.trim_end_matches(".json");
Firebase { uri }
}

fn build_uri(&self, path: &str) -> Url {
let mut new_path = String::new();

if let Some(segments) = self.uri.path_segments() {
for segment in segments {
let clean_segment = segment.trim_end_matches(".json");
new_path.push_str(clean_segment);
new_path.push('/');
}
new_path += format!("{}/", path).as_str();
}

new_path += path;
new_path.push_str(path);

if new_path.find(".json").is_some() {
new_path = new_path.trim_end_matches(".json").to_string();
}
let final_path = if new_path.ends_with(".json") {

This comment has been minimized.

Copy link
@allsey87

allsey87 Nov 21, 2024

I think something like this would be a bit more idiomatic:

let final_path = match new_path.strip_suffix(".json") {
    Some(path) => path,
    None => new_path
}
new_path.trim_end_matches(".json").to_string()
} else {
new_path
};

let mut uri = self.uri.clone();
uri.set_path(&format!("{}.json", new_path));
Self { uri }
uri.set_path(&format!("{}.json", final_path));

uri
}

/// ```rust
Expand All @@ -148,67 +157,38 @@ impl Firebase {

async fn request(&self, method: Method, data: Option<Value>) -> RequestResult<Response> {
let client = reqwest::Client::new();

return match method {
Method::GET => {
let request = client.get(self.uri.to_string()).send().await;
match request {
Ok(response) => {
if response.status() == StatusCode::from_u16(200).unwrap() {
return match response.text().await {
Ok(data) => {
if data.as_str() == "null" {
return Err(RequestError::NotFoundOrNullBody);
}
return Ok(Response { data });
}
Err(_) => Err(RequestError::NotJSON),
};
} else {
Err(RequestError::NetworkError)
}
}
Err(_) => return Err(RequestError::NetworkError),
}
}
Method::POST => {
if !data.is_some() {
let request = match method {
Method::GET => client.get(self.uri.to_string()).send().await,
Method::PUT | Method::PATCH | Method::POST => {
if data.is_none() {
return Err(RequestError::SerializeError);
}

let request = client.post(self.uri.to_string()).json(&data).send().await;
match request {
Ok(response) => {
let data = response.text().await.unwrap();
Ok(Response { data })
}
Err(_) => Err(RequestError::NetworkError),
}
let builder = if method == Method::PUT {
client.put(self.uri.to_string())
} else if method == Method::POST {
client.post(self.uri.to_string())
} else {
client.patch(self.uri.to_string())
};
builder.json(&data).send().await
}
Method::PATCH => {
if !data.is_some() {
return Err(RequestError::SerializeError);
}
Method::DELETE => client.delete(self.uri.to_string()).send().await,
};

let request = client.patch(self.uri.to_string()).json(&data).send().await;
match request {
Ok(response) => {
let data = response.text().await.unwrap();
Ok(Response { data })
match request {
Ok(response) => match response.status() {
StatusCode::OK => {
let response_text = response.text().await.unwrap_or_default();
if response_text == "null" {
Err(RequestError::NotFoundOrNullBody)
} else {
Ok(Response { data: response_text })
}
Err(_) => Err(RequestError::NetworkError),
}
}
Method::DELETE => {
let request = client.delete(self.uri.to_string()).send().await;
match request {
Ok(_) => Ok(Response {
data: String::default(),
}),
Err(_) => Err(RequestError::NetworkError),
}
}
};
_ => Err(RequestError::NetworkError),
},
Err(_) => Err(RequestError::NetworkError),
}
}

async fn request_generic<T>(&self, method: Method) -> RequestResult<T>
Expand Down Expand Up @@ -250,6 +230,31 @@ impl Firebase {
self.request(Method::POST, Some(data)).await
}

/// ```rust
/// use firebase_rs::Firebase;
/// use serde::{Serialize, Deserialize};
///
/// #[derive(Serialize, Deserialize, Debug)]
/// struct User {
/// name: String
/// }
///
/// # async fn run() {
/// let user = User { name: String::default() };
/// let mut firebase = Firebase::new("https://myfirebase.firebaseio.com").unwrap().at("users");
/// let users = firebase.set_with_key("myKey", &user).await;
/// # }
/// ```
pub async fn set_with_key<T>(&mut self, key: &str, data: &T) -> RequestResult<Response>
where
T: Serialize + DeserializeOwned + Debug,
{
self.uri = self.build_uri(key);
let data = serde_json::to_value(&data).unwrap();

self.request(Method::PUT, Some(data)).await
}

/// ```rust
/// use std::collections::HashMap;
/// use firebase_rs::Firebase;
Expand Down Expand Up @@ -368,4 +373,4 @@ mod tests {
async fn with_sse_events() {
// TODO: SSE Events Test
}
}
}

0 comments on commit bf352f7

Please sign in to comment.