Skip to content

Commit

Permalink
use vec instead of hashmap
Browse files Browse the repository at this point in the history
  • Loading branch information
NotThatRqd committed Oct 29, 2023
1 parent fe51c1e commit c617902
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "btnify"
version = "0.1.0"
version = "0.2.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
5 changes: 2 additions & 3 deletions src/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ use serde::{Deserialize, Serialize};
pub struct Button<S: Send + Sync + 'static> {
// todo: add "get_name" and "get_id" which return immutable str slice
pub name: String,
pub id: String,
pub handler: Box<dyn (Fn(&S) -> ButtonResponse) + Send + Sync>
}

Expand All @@ -48,18 +47,18 @@ impl<S: Send + Sync + 'static> Button<S> {
///
/// `Handler` is a function or closure that takes a reference to a user provided state (`S`) and
/// returns `ButtonResponse`. It will be called whenever this button is pressed.
// todo: implement Button::from<&str>
pub fn new<T: Send + Sync + Fn(&S) -> ButtonResponse + 'static>(name: &str, handler: T) -> Button<S> {
Button {
name: name.to_string(),
id: name.to_lowercase(),
handler: Box::new(handler)
}
}
}

#[derive(Deserialize, Debug)]
pub(crate) struct ButtonInfo {
pub id: String
pub id: usize
// todo: allow any extra data to be sent
}

Expand Down
20 changes: 10 additions & 10 deletions src/html_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ pub(super) fn create_page_html<'a, S: Send + Sync + 'static>(buttons: impl Itera
</head>
<body>
{}
<button onclick="showMessage(prompt('enter id'))">other</button>
<script>
async function showMessage(id) {{
Expand All @@ -36,12 +35,13 @@ pub(super) fn create_page_html<'a, S: Send + Sync + 'static>(buttons: impl Itera

fn create_buttons_html<'a, S: Send + Sync + 'static>(buttons: impl Iterator<Item = &'a Button<S>>) -> String {
buttons
.map(create_button_html)
.enumerate()
.map(|(id, b)| create_button_html(b, id))
.collect()
}

fn create_button_html<S: Send + Sync + 'static>(button: &Button<S>) -> String {
format!(r#"<button onclick="showMessage('{}')">{}</button>"#, button.id, button.name)
fn create_button_html<S: Send + Sync + 'static>(button: &Button<S>, id: usize) -> String {
format!(r#"<button onclick="showMessage({})">{}</button>"#, id, button.name)
}

#[cfg(test)]
Expand All @@ -51,13 +51,13 @@ mod tests {

/// Dummy function that can be used as a button handler
fn dummy(_: &()) -> ButtonResponse {
todo!()
unimplemented!()
}

#[test]
fn create_button_test() {
let button = create_button_html(&Button::new("Count", dummy));
assert_eq!(button, r#"<button onclick="showMessage('count')">Count</button>"#);
let button = create_button_html(&Button::new("Count", dummy), 0);
assert_eq!(button, r#"<button onclick="showMessage(0)">Count</button>"#);
}

#[test]
Expand All @@ -71,8 +71,8 @@ mod tests {
let buttons_html = create_buttons_html(list.iter());

// todo: make cleaner using raw string
assert_eq!(buttons_html, "<button onclick=\"showMessage('count')\">Count</button>\
<button onclick=\"showMessage('ping')\">Ping</button>\
<button onclick=\"showMessage('greet')\">Greet</button>");
assert_eq!(buttons_html, "<button onclick=\"showMessage(0)\">Count</button>\
<button onclick=\"showMessage(1)\">Ping</button>\
<button onclick=\"showMessage(2)\">Greet</button>");
}
}
13 changes: 6 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::collections::HashMap;
use std::net::SocketAddr;
use std::sync::Arc;
use axum::{Json, Router};
Expand All @@ -17,13 +16,13 @@ pub mod button;
pub async fn bind_server<S: Send + Sync + 'static>(addr: &SocketAddr, buttons: Vec<Button<S>>, user_state: S) {
let page = Html(create_page_html(buttons.iter()));

// todo: what if two buttons have the same id?
let buttons_map = buttons.into_iter()
.map(|b| (b.id, b.handler))
let buttons_map = buttons
.into_iter()
.map(|b| b.handler)
.collect();

let btnify_state = Arc::new(BtnifyState {
buttons_map,
button_handlers: buttons_map,
user_state,
page
});
Expand All @@ -44,7 +43,7 @@ async fn get_root<S: Send + Sync>(State(state): State<Arc<BtnifyState<S>>>) -> H
}

async fn post_root<S: Send + Sync>(State(state): State<Arc<BtnifyState<S>>>, Json(info): Json<ButtonInfo>) -> Json<ButtonResponse> {
let handler = state.buttons_map.get(&info.id);
let handler = state.button_handlers.get(info.id);

let res = match handler {
Some(handler) => handler(&state.user_state),
Expand All @@ -55,7 +54,7 @@ async fn post_root<S: Send + Sync>(State(state): State<Arc<BtnifyState<S>>>, Jso
}

struct BtnifyState<S> {
buttons_map: HashMap<String, Box<dyn (Fn(&S) -> ButtonResponse) + Send + Sync>>,
button_handlers: Vec<Box<dyn (Fn(&S) -> ButtonResponse) + Send + Sync>>,
user_state: S,
page: Html<String>
}

0 comments on commit c617902

Please sign in to comment.