-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add unit selector with seconds and bytes (#13)
uses `humantime` and `ubyte` Closes #12
- Loading branch information
Showing
11 changed files
with
236 additions
and
85 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,5 @@ | ||
mod number_input; | ||
mod select_input; | ||
|
||
pub(crate) use number_input::NumberInput; | ||
pub(crate) use select_input::{SelectInput, SelectOption}; |
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,58 @@ | ||
use leptos::ev::Event; | ||
use leptos::{ | ||
component, event_target_value, view, Callable, Callback, CollectView, IntoView, ReadSignal, | ||
SignalSet, SignalWith, WriteSignal, | ||
}; | ||
use std::fmt::Display; | ||
use std::str::FromStr; | ||
|
||
pub(crate) trait SelectOption { | ||
fn label(&self) -> &'static str; | ||
} | ||
|
||
#[component] | ||
pub(crate) fn SelectInput<T>( | ||
#[prop(into)] get: ReadSignal<T>, | ||
#[prop(into)] set: WriteSignal<T>, | ||
#[prop(into)] options: Vec<T>, | ||
#[prop(into, optional)] on_change: Option<Callback<Event>>, | ||
#[prop(into)] label: String, | ||
) -> impl IntoView | ||
where | ||
T: SelectOption + Display + PartialEq + FromStr + Copy + 'static, | ||
{ | ||
let on_change = move |ev| { | ||
let Ok(new_value) = event_target_value(&ev).parse::<T>() else { | ||
// impossible until somebody changes selector in their browser or wrong impl of `T: FromStr` | ||
log::debug!("[select-input] failed to parse value"); | ||
return; | ||
}; | ||
log::debug!("[select-input] new value is: {new_value}"); | ||
|
||
set.set(new_value); | ||
if let Some(callback) = on_change { | ||
callback.call(ev); | ||
} | ||
}; | ||
|
||
let options_view = options | ||
.into_iter() | ||
.map(|option| { | ||
let is_selected = move || get.with(|v| v == &option); | ||
view! { | ||
<option value=option.to_string() selected=is_selected> | ||
{ option.label() } | ||
</option> | ||
} | ||
}) | ||
.collect_view(); | ||
|
||
view! { | ||
<label class="form-label"> | ||
{label} | ||
<select class="form-select" on:change=on_change > | ||
{options_view} | ||
</select> | ||
</label> | ||
} | ||
} |
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,64 @@ | ||
use std::ops::Deref; | ||
|
||
#[derive(Debug, Clone)] | ||
pub(crate) struct Buckets(Vec<Bucket>); | ||
|
||
#[derive(Debug, Clone)] | ||
pub(crate) struct Bucket { | ||
number: u32, | ||
le: f64, | ||
} | ||
|
||
impl Buckets { | ||
pub(crate) fn calculate(initial_value: f64, factor: f64, num_of_buckets: u32) -> Self { | ||
// Include last bucket, which is open ended | ||
// TODO: use bounded integer type to restrict passing too large values. | ||
// Overflow isn't possible due to validations, but this api is isolated | ||
let num_of_buckets = num_of_buckets | ||
.checked_add(1) | ||
.expect("number of buckets - overflow"); | ||
let mut buckets = Vec::with_capacity(num_of_buckets as usize); | ||
let mut next_value = initial_value; | ||
|
||
// starting from second bucket, since first one is already added | ||
for bucket_num in 1..num_of_buckets { | ||
buckets.push(Bucket::new(bucket_num, next_value)); | ||
next_value *= factor; | ||
} | ||
// last bucket is open ended | ||
buckets.push(Bucket::new(num_of_buckets, f64::INFINITY)); | ||
|
||
Self(buckets) | ||
} | ||
} | ||
|
||
impl Bucket { | ||
fn new(number: u32, le: f64) -> Self { | ||
Self { number, le } | ||
} | ||
|
||
pub fn number(&self) -> u32 { | ||
self.number | ||
} | ||
|
||
pub fn le(&self) -> f64 { | ||
self.le | ||
} | ||
} | ||
|
||
impl Deref for Buckets { | ||
type Target = Vec<Bucket>; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
|
||
impl IntoIterator for Buckets { | ||
type Item = Bucket; | ||
type IntoIter = std::vec::IntoIter<Self::Item>; | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
self.0.into_iter() | ||
} | ||
} |
Oops, something went wrong.