-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
214 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use super::ServerUrlItem; | ||
use crate::{ | ||
constants::{SERVER_URL_BUCKET_DEFAULT_ITEM_ID, SERVER_URL_BUCKET_MAX_ITEMS}, | ||
types::profile::UID, | ||
}; | ||
use serde::{Deserialize, Serialize}; | ||
use std::collections::HashMap; | ||
use std::time::{SystemTime, UNIX_EPOCH}; | ||
use url::Url; | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] | ||
pub struct ServerUrlBucket { | ||
/// User ID | ||
pub uid: UID, | ||
/// [`HashMap`] Key is the [`ServerUrlItem`]`.id`. | ||
pub items: HashMap<String, ServerUrlItem>, | ||
} | ||
|
||
impl ServerUrlBucket { | ||
/// Create a new [`ServerUrlBucket`] with the base URL inserted. | ||
pub fn new(uid: UID, base_url: Url) -> Self { | ||
let mut items = HashMap::new(); | ||
|
||
let server_url_item = ServerUrlItem { | ||
id: SERVER_URL_BUCKET_DEFAULT_ITEM_ID.to_string(), | ||
url: base_url.clone(), | ||
mtime: Self::current_timestamp() as i64, | ||
selected: true, | ||
}; | ||
|
||
// Use the item's id as the key in the HashMap | ||
items.insert(server_url_item.id.clone(), server_url_item); | ||
|
||
ServerUrlBucket { uid, items } | ||
} | ||
|
||
fn current_timestamp() -> u64 { | ||
SystemTime::now() | ||
.duration_since(UNIX_EPOCH) | ||
.expect("Time went backwards") | ||
.as_secs() | ||
} | ||
|
||
pub fn merge_bucket(&mut self, bucket: ServerUrlBucket) { | ||
if self.uid == bucket.uid { | ||
self.merge_items(bucket.items.into_values().collect()); | ||
} | ||
} | ||
|
||
pub fn merge_items(&mut self, items: Vec<ServerUrlItem>) { | ||
for new_item in items.into_iter() { | ||
match self.items.get_mut(&new_item.id) { | ||
Some(item) => { | ||
*item = new_item; | ||
} | ||
None => { | ||
if self.items.len() < SERVER_URL_BUCKET_MAX_ITEMS { | ||
self.items.insert(new_item.id.to_owned(), new_item); | ||
} else { | ||
let oldest_item_id_option = self | ||
.items | ||
.values() | ||
.filter(|item| item.id != SERVER_URL_BUCKET_DEFAULT_ITEM_ID) | ||
.min_by_key(|item| item.mtime) | ||
.map(|item| item.id.clone()); | ||
|
||
if let Some(oldest_item_id) = oldest_item_id_option { | ||
if new_item.mtime > self.items[&oldest_item_id].mtime { | ||
self.items.remove(&oldest_item_id); | ||
self.items.insert(new_item.id.to_owned(), new_item); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn edit_item(&mut self, id: &str, new_url: Url) -> Result<(), String> { | ||
if let Some(item) = self.items.get_mut(id) { | ||
item.url = new_url; | ||
item.mtime = Self::current_timestamp() as i64; | ||
Ok(()) | ||
} else { | ||
Err("Item not found".to_string()) | ||
} | ||
} | ||
|
||
/// Delete an item by its ID | ||
pub fn delete_item(&mut self, id: &str) -> Result<(), String> { | ||
if id == SERVER_URL_BUCKET_DEFAULT_ITEM_ID { | ||
return Err("Cannot remove the base URL item.".to_string()); | ||
} | ||
if self.items.remove(id).is_some() { | ||
Ok(()) | ||
} else { | ||
Err("Item not found".to_string()) | ||
} | ||
} | ||
|
||
pub fn selected_item(&self) -> Option<&ServerUrlItem> { | ||
self.items.values().find(|item| item.selected) | ||
} | ||
|
||
pub fn selected_item_url(&self) -> Option<Url> { | ||
self.selected_item().map(|item| item.url.clone()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
use serde::{Deserialize, Serialize}; | ||
use url::Url; | ||
|
||
/// Server URL Item | ||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] | ||
pub struct ServerUrlItem { | ||
/// Unique ID | ||
pub id: String, | ||
/// URL | ||
pub url: Url, | ||
/// Timestamp | ||
pub mtime: i64, | ||
/// Selected | ||
pub selected: bool, | ||
} | ||
|
||
impl ServerUrlItem { | ||
pub fn new(id: String, url: Url, mtime: i64) -> Self { | ||
ServerUrlItem { | ||
id, | ||
url, | ||
mtime, | ||
selected: false, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.