seed-rs / seed

A Rust framework for creating web apps
MIT License
3.81k stars 155 forks source link

Feature request: impl From<Node<Y>> for Node<X> where Y: Into<X> #653

Open sidju opened 2 years ago

sidju commented 2 years ago

I am home rolling a frontend and deeply enjoying the flexibility offered by seed. I have essentially built a half-isolated component structure with a global Msg (views branch down with parts of the model in a tree structure). Overall this works absurdly well with the APIs, but I'd like to be able to return Node from my component view functions instead of manually wrapping my callbacks into the global Msg type.

The way I envision this could be made possible is by having a general implementation to convert Node into Node if LocalMsg can be converted into Msg (infallibly in most reasonable cases, incl. mine). I expect this might be a bit tricky, but hope it can be done relatively easily.

sidju commented 2 years ago

Seemingly impossible right now, due to this not being supported by rust: https://github.com/rust-lang/rfcs/issues/1834

(To clarify, since it cannot be declared that X != Y the suggested impl overlaps with the general implementation that Self implements From (noop), which is a compilation error.)

sidju commented 2 years ago

Current workaround is to use .map_msg on the Node to covert it.

The mapped function can further contain the Y to X implementation, saving a trait implementation if only called in one location.

Another path to take would be to require that View returns IntoNode instead of Node. This would solve the current implementation collision with Into and enable the frameword to automatically convert as suitable, but this will make the framework a bit more complex and introduce if/else type mismatches if the user doesn't convert on every branch. Right now I can't envision how it would be any better than this workaround.

MartinKavik commented 2 years ago

I've chosen .map_msg to make it consistent with other entities (e.g. Cmd) and with the primary inspiration - https://package.elm-lang.org/packages/elm/html/1.0.0/Html#map. Also there is a monster in the code base - https://github.com/seed-rs/seed/blob/cce9685c05b07043ae42d39bcb9023f74a954ae0/src/lib.rs#L61-L90 - abusing Any to simulate something like specialiazation. So I can imagine the Seed APIs could be refactored in the future once required Rust features appear in the stable channel. I think your idea could be one of them (if I understand it correctly - I always suggest to write super basic examples in the issue description.)