I'm currently using Dioxus to generate a page that dynamically changes an image carousel.
What I want to achieve right now is to use the max function to compare the result of use_state to prevent the number from coming lower from 1.
Here's a simple app:
use dioxus::{events::*, hooks::UseState, prelude::*};
use log::{info, LevelFilter};
use std::cmp::{max, Ordering};
impl PartialOrd for UseState<i32> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for UseState<i32> {
fn cmp(&self, other: &Self) -> Ordering {
self.x.cmp(&other.x)
}
}
/**
* Specify <link data-trunk rel="copy-dir" href="src/assets" />
* in the index.html to copy the files!!
*
* You'll see them in the dist directory!
*/
fn main() {
dioxus_logger::init(LevelFilter::Info).expect("failed to init logger");
dioxus::web::launch(app);
}
fn app(cx: Scope) -> Element {
let mut index = use_state(&cx, || 1);
let val = index.get() as &i32;
let num = 1 as i32;
let change_evt = move |evt: KeyboardEvent| match evt.key.as_str() {
"ArrowRight" => index += 1,
"ArrowLeft" => index = max(&num.try_into(), &val.try_into()),
_ => {}
};
let url = format!("/assets/manga/one_piece/1042/0{}.jpg", index);
cx.render(rsx!(img {
src: "{url}",
}
div {
class: "display",
onkeydown: change_evt,
button {
class: "but",
onclick: move |evt| {
println!("{evt:?}");
info!("{evt:?}");
},
"Press me!"
},
},
))
}
I thought at the beginning that using index.get() would yield me the i32 needed to compare with max().
But it complained and told me I needed to implement PartialOrd for UseState{Integer}.
I'm currently stuck trying to implement it.
Here's my cargo.toml
[package]
name = "rust-manga"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dioxus = { version = "0.2.4", features = ["web", "html"] }
dioxus-html = "0.2.1"
dioxus-logger = "0.3.0"
log = "0.4.17"
When implementing a trait for something (such as
impl PartialOrd for UseState), then at least one of the two components must belong to the crate where theimplis defined. But bothPartialOrdandUseStateare defined outside your crate, so you cannot do that.There are two options:
The downside is that you would need to wrap instances of where you use
dioxus::hooks::UseStatein your custom type, at least whenever you want to compare things.UseState:If
UseStatedoesn't implement the traits necessary to pass it tostd::cmp::max, we have to get the inner value. It does offer multiple ways to do that, such asUseState::get(),UseState::current()or an implementation ofDeref.So we could do
max(num, *index.get()), where.get()gets a&i32, and we derefence that to get the value. Ormax(num, **index), usingDeref.However, we still can't assign that to
index, as ani32can't be assigned to anUseState.That's what
UseState::modify()is for. It allows you to modify the value in place: