I am writing a program using crate iced
. However, type conversions between elements can be quite confusing.
How can I fix the code to pass compilation?
The first problem
I want to load a new image when Message::ImageChanged
is called.
Here is my code:
enum Message {
Loaded(Result<State, Error>),
ImageChanged(u32),
}
pub struct State {
// ...
}
impl Application for Memories {
fn update(&mut self, message: Message) -> Command<Message> {
match self {
Memories::Loading => Command::none(),
Memories::Loaded(state) => {
match state.stage {
Stage::ChoosingCharacter(chosen) => match message {
Message::ImageChanged(next) => {
*self = Memories::Loading;
chosen.on_image = next;
let img_path = state
.idxtable
.get("image");
Command::perform(async { // line 110
chosen.image = Some(
state
.get_image(img_path.to_string())
.await
.expect("Cannot get image.")
);
state
}, Message::Loaded) // line 118
}
which generated the following error:
error[E0631]: type mismatch in function arguments
--> src\main.rs:118:32
|
63 | Loaded(Result<State, Error>),
| ------ found signature defined here
...
110 | Command::perform(async {
| ---------------- required by a bound introduced by this call
...
118 | }, Message::Loaded)
| ^^^^^^^^^^^^^^^ expected due to this
|
= note: expected function signature `fn(&mut State) -> _`
found function signature `fn(Result<State, Error>) -> _`
note: required by a bound in `iced::Command::<T>::perform`
--> D:\Scoop\persist\rustup-msvc\.cargo\registry\src\github.com-1ecc6299db9ec823\iced_native-0.7.0\src\command.rs:39:17
|
39 | f: impl FnOnce(T) -> A + 'static + MaybeSend,
| ^^^^^^^^^^^^^^ required by this bound in `iced::Command::<T>::perform`
This is the simliar code in pokedex
:
The second problem
Just like the pokemon
(line 77) example which indirectly calls image::viewer(iced::widget::image::Handle) -> Viewer<iced::widget::image::Handle>
to display image by a handle, I tried to create an element with an image handle but received such type conversion errors.
Code from the example:
My code with wrong type conversions:
enum Stage {
ChoosingCharacter(ChoosingState),
ShowingPlots,
Graduated,
}
pub struct ChoosingState {
chosen_character: u32,
on_image: u32,
image: Option<image::Handle>,
}
impl Application for Memories {
// --snip--
fn view(&self) -> Element<Message> {
match self {
Memories::Loaded(state) => {
match state.stage {
Stage::ChoosingCharacter(chosen) => row![
match chosen.image {
Some(handle) => image::viewer(handle), // line 149
None => text("Not able to load image.").size(40)
}, // line 151
Self::show_name("Class 1")
]
which generated the following error:
error[E0308]: `match` arms have incompatible types
--> src\main.rs:150:37
|
148 | / match chosen.image {
149 | | Some(handle) => image::viewer(handle),
| | --------------------- this is found to be of type `Viewer<iced::widget::image::Handle>`
150 | | None => text("Not able to load image.").size(40)
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Viewer`, found struct `iced_native::widget::text::Text`
151 | | },
| |_________________________- `match` arms have incompatible types
|
= note: expected struct `Viewer<iced::widget::image::Handle>`
found struct `iced_native::widget::text::Text<'_, _>`
New error such as error[E0283]: type annotations needed
will be produced if I add into()
to it.
If you can help me solve this problem, could you also help me clarify the topological relationships between iced::widget::image::Viewer
, iced::Element
, and iced::Renderer
?
Thanks a lot.