Remove the `Message` generic now that `DynMessage` isn't `Send`. (#1122)

Follow-up from #1117.

I've tried to check the docs - I've changed the instance added by
https://github.com/linebender/xilem/pull/408
This commit is contained in:
Daniel McNab 2025-07-09 11:22:06 +01:00 committed by GitHub
parent 547605d20e
commit c0c1f7452c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
36 changed files with 288 additions and 330 deletions

View File

@ -80,7 +80,7 @@ The associated Elements of the `View` trait are either DOM nodes for `xilem_web`
## Code Organisation
### `xilem_core`
Contains the `View` trait, and other general implementations. Is also contains the `Message`, `MessageResult`, `Id` types and the tree-structrure tracking.
Contains the `View` trait, and other general implementations. Is also contains the `DynMessage`, `MessageResult`, `Id` types and the tree-structrure tracking.
### `xilem_web/`
An implementation of Xilem running on the DOM.

View File

@ -277,7 +277,7 @@ where
id_path: &[xilem_core::ViewId],
message: DynMessage,
app_state: &mut State,
) -> xilem_core::MessageResult<Action, DynMessage> {
) -> xilem_core::MessageResult<Action> {
match id_path.split_first() {
Some((&CHILD1_VIEW_ID, rest)) => {
self.child1

View File

@ -156,7 +156,7 @@ where
id_path: &[xilem_core::ViewId],
message: DynMessage,
app_state: &mut State,
) -> xilem_core::MessageResult<Action, DynMessage> {
) -> xilem_core::MessageResult<Action> {
self.child
.message(&mut view_state.child, id_path, message, app_state)
}

View File

@ -92,7 +92,7 @@ impl<State, Action> View<State, Action, ViewCtx> for VariableLabel {
fn build(&self, ctx: &mut ViewCtx, app_state: &mut State) -> (Self::Element, Self::ViewState) {
let (label, ()) = ctx.with_id(ViewId::new(0), |ctx| {
View::<State, Action, _, _>::build(&self.label, ctx, app_state)
View::<State, Action, _>::build(&self.label, ctx, app_state)
});
let widget_pod = ctx.create_pod(
widgets::VariableLabel::from_label_pod(label.into_widget_pod())
@ -110,7 +110,7 @@ impl<State, Action> View<State, Action, ViewCtx> for VariableLabel {
app_state: &mut State,
) {
ctx.with_id(ViewId::new(0), |ctx| {
View::<State, Action, _, _>::rebuild(
View::<State, Action, _>::rebuild(
&self.label,
&prev.label,
&mut (),
@ -137,7 +137,7 @@ impl<State, Action> View<State, Action, ViewCtx> for VariableLabel {
app_state: &mut State,
) {
ctx.with_id(ViewId::new(0), |ctx| {
View::<State, Action, _, _>::teardown(
View::<State, Action, _>::teardown(
&self.label,
&mut (),
ctx,

View File

@ -116,7 +116,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.sequence
.seq_message(view_state, id_path, message, app_state)
}

View File

@ -83,7 +83,7 @@ where
id_path: &[xilem_core::ViewId],
message: xilem_core::DynMessage,
app_state: &mut State,
) -> xilem_core::MessageResult<(), xilem_core::DynMessage> {
) -> xilem_core::MessageResult<()> {
self.root_widget_view
.message(view_state, id_path, message, app_state)
}

View File

@ -26,7 +26,7 @@ use crate::{
///
/// Libraries using `xilem_core` are expected to have a type alias for their own `AnyView`, which specifies
/// the `Context` and `Element` types.
pub trait AnyView<State, Action, Context, Element: ViewElement, Message = DynMessage> {
pub trait AnyView<State, Action, Context, Element: ViewElement> {
/// Get an [`Any`] reference to `self`.
fn as_any(&self) -> &dyn Any;
@ -38,7 +38,7 @@ pub trait AnyView<State, Action, Context, Element: ViewElement, Message = DynMes
&self,
dyn_state: &mut AnyViewState,
ctx: &mut Context,
prev: &dyn AnyView<State, Action, Context, Element, Message>,
prev: &dyn AnyView<State, Action, Context, Element>,
element: Element::Mut<'_>,
app_state: &mut State,
);
@ -59,19 +59,18 @@ pub trait AnyView<State, Action, Context, Element: ViewElement, Message = DynMes
&self,
dyn_state: &mut AnyViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message>;
) -> MessageResult<Action>;
}
impl<State, Action, Context, DynamicElement, Message, V>
AnyView<State, Action, Context, DynamicElement, Message> for V
impl<State, Action, Context, DynamicElement, V> AnyView<State, Action, Context, DynamicElement>
for V
where
DynamicElement: AnyElement<V::Element, Context>,
Context: ViewPathTracker,
V: View<State, Action, Context, Message> + 'static,
V: View<State, Action, Context> + 'static,
V::ViewState: 'static,
Message: 'static,
{
fn as_any(&self) -> &dyn Any {
self
@ -98,7 +97,7 @@ where
&self,
dyn_state: &mut AnyViewState,
ctx: &mut Context,
prev: &dyn AnyView<State, Action, Context, DynamicElement, Message>,
prev: &dyn AnyView<State, Action, Context, DynamicElement>,
mut element: DynamicElement::Mut<'_>,
app_state: &mut State,
) {
@ -155,9 +154,9 @@ where
&self,
dyn_state: &mut AnyViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let state = dyn_state
.inner_state
.downcast_mut()
@ -183,15 +182,14 @@ pub struct AnyViewState {
generation: u64,
}
impl<State, Action, Context, Element, Message> ViewMarker for dyn AnyView<State, Action, Context, Element, Message> {}
impl<State, Action, Context, Element, Message> View<State, Action, Context, Message> for dyn AnyView<State, Action, Context, Element, Message>
impl<State, Action, Context, Element> ViewMarker for dyn AnyView<State, Action, Context, Element> {}
impl<State, Action, Context, Element> View<State, Action, Context> for dyn AnyView<State, Action, Context, Element>
where
// Element must be `static` so it can be downcasted
Element: ViewElement + 'static,
Context: ViewPathTracker + 'static,
State: 'static,
Action: 'static,
Message: 'static,
{
type Element = Element;
@ -226,28 +224,27 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
self.dyn_message(view_state, id_path, message, app_state)
}
}
// TODO: IWBN if we could avoid this
impl<State, Action, Context, Element, Message> ViewMarker
for dyn AnyView<State, Action, Context, Element, Message> + Send
impl<State, Action, Context, Element> ViewMarker
for dyn AnyView<State, Action, Context, Element> + Send
{
}
impl<State, Action, Context, Element, Message> View<State, Action, Context, Message>
for dyn AnyView<State, Action, Context, Element, Message> + Send
impl<State, Action, Context, Element> View<State, Action, Context>
for dyn AnyView<State, Action, Context, Element> + Send
where
// Element must be `static` so it can be downcasted
Element: ViewElement + 'static,
Context: ViewPathTracker + 'static,
State: 'static,
Action: 'static,
Message: 'static,
{
type Element = Element;
@ -282,26 +279,25 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
self.dyn_message(view_state, id_path, message, app_state)
}
}
impl<State, Action, Context, Element, Message> ViewMarker
for dyn AnyView<State, Action, Context, Element, Message> + Send + Sync
impl<State, Action, Context, Element> ViewMarker
for dyn AnyView<State, Action, Context, Element> + Send + Sync
{
}
impl<State, Action, Context, Element, Message> View<State, Action, Context, Message>
for dyn AnyView<State, Action, Context, Element, Message> + Send + Sync
impl<State, Action, Context, Element> View<State, Action, Context>
for dyn AnyView<State, Action, Context, Element> + Send + Sync
where
// Element must be `static` so it can be downcasted
Element: ViewElement + 'static,
Context: ViewPathTracker + 'static,
State: 'static,
Action: 'static,
Message: 'static,
{
type Element = Element;
@ -336,26 +332,25 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
self.dyn_message(view_state, id_path, message, app_state)
}
}
impl<State, Action, Context, Element, Message> ViewMarker
for dyn AnyView<State, Action, Context, Element, Message> + Sync
impl<State, Action, Context, Element> ViewMarker
for dyn AnyView<State, Action, Context, Element> + Sync
{
}
impl<State, Action, Context, Element, Message> View<State, Action, Context, Message>
for dyn AnyView<State, Action, Context, Element, Message> + Sync
impl<State, Action, Context, Element> View<State, Action, Context>
for dyn AnyView<State, Action, Context, Element> + Sync
where
// Element must be `static` so it can be downcasted
Element: ViewElement + 'static,
Context: ViewPathTracker + 'static,
State: 'static,
Action: 'static,
Message: 'static,
{
type Element = Element;
@ -390,9 +385,9 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
self.dyn_message(view_state, id_path, message, app_state)
}
}

View File

@ -6,11 +6,11 @@ use alloc::sync::Arc;
use core::fmt::{Debug, Display};
use core::marker::PhantomData;
use crate::{AnyMessage, DynMessage, NoElement, SendMessage, View, ViewId, ViewPathTracker};
use crate::{AnyMessage, NoElement, SendMessage, View, ViewId, ViewPathTracker};
/// A `Context` for a [`View`] implementation which supports
/// asynchronous message reporting.
pub trait AsyncCtx<Message = DynMessage>: ViewPathTracker {
pub trait AsyncCtx: ViewPathTracker {
/// Get a [`RawProxy`] for this context.
// TODO: Maybe store the current path within this Proxy?
fn proxy(&mut self) -> Arc<dyn RawProxy>;
@ -100,16 +100,16 @@ impl<M: AnyMessage + Send> MessageProxy<M> {
}
/// A [`View`] which has no element type.
pub trait PhantomView<State, Action, Context, Message = DynMessage>:
View<State, Action, Context, Message, Element = NoElement>
pub trait PhantomView<State, Action, Context>:
View<State, Action, Context, Element = NoElement>
where
Context: ViewPathTracker,
{
}
impl<State, Action, Context, Message, V> PhantomView<State, Action, Context, Message> for V
impl<State, Action, Context, V> PhantomView<State, Action, Context> for V
where
V: View<State, Action, Context, Message, Element = NoElement>,
V: View<State, Action, Context, Element = NoElement>,
Context: ViewPathTracker,
{
}

View File

@ -11,7 +11,7 @@ use core::fmt::Debug;
///
/// [`View::message`]: crate::View::message
#[derive(Default, Debug)]
pub enum MessageResult<Action, Message = DynMessage> {
pub enum MessageResult<Action> {
/// An action for a parent message handler to use
///
/// This allows for sub-sections of your app to use an elm-like architecture
@ -26,12 +26,12 @@ pub enum MessageResult<Action, Message = DynMessage> {
/// does not require the element tree to be recreated.
Nop,
/// The view this message was being routed to no longer exists.
Stale(Message),
Stale(DynMessage),
}
impl<A, Message> MessageResult<A, Message> {
impl<A> MessageResult<A> {
/// Maps the action type `A` to `B`, i.e. [`MessageResult<A>`] to [`MessageResult<B>`]
pub fn map<B>(self, f: impl FnOnce(A) -> B) -> MessageResult<B, Message> {
pub fn map<B>(self, f: impl FnOnce(A) -> B) -> MessageResult<B> {
match self {
Self::Action(a) => MessageResult::Action(f(a)),
Self::RequestRebuild => MessageResult::RequestRebuild,
@ -49,10 +49,6 @@ impl<A, Message> MessageResult<A, Message> {
/// To convert a `DynMessage` into its concrete message type, you should use
/// [`downcast`](Self::downcast).
///
/// This type is a struct rather than (say) a type alias, because type aliases are sometimes resolved by
/// rust-analyzer when autofilling a trait, which can also lead to buggy behaviour (we've previously seen
/// `Box<dyn Box<dyn Message>>` be generated).
///
/// If the message contains sensitive data, make sure this isn't output in its `Debug` implementation,
/// as that may be called by the Xilem runtime (e.g. due to a bug meaning messages are redirected) or
/// any parent views. That is, views do not need to be designed as if the `Debug` implementation
@ -60,6 +56,8 @@ impl<A, Message> MessageResult<A, Message> {
///
/// [`View`]: crate::View
#[derive(Debug)]
// This type is a struct rather than (say) a type alias, because type aliases are sometimes resolved by
// rust-analyzer when autofilling a trait, and we want to always use a consistent name for this type.
pub struct DynMessage(pub Box<dyn AnyMessage>);
impl DynMessage {

View File

@ -78,7 +78,7 @@ impl<T> Default for AppendVec<T> {
/// - Tuples of `ViewSequences` with up to 15 elements.
/// These can be nested if an ad-hoc sequence of more than 15 sequences is needed.
///
pub trait ViewSequence<State, Action, Context, Element, Message = DynMessage>: 'static
pub trait ViewSequence<State, Action, Context, Element>: 'static
where
Context: ViewPathTracker,
Element: ViewElement,
@ -127,9 +127,9 @@ where
&self,
seq_state: &mut Self::SeqState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message>;
) -> MessageResult<Action>;
}
/// A temporary "splice" to add, update and delete in an (ordered) sequence of elements.
@ -150,11 +150,10 @@ pub trait ElementSplice<Element: ViewElement> {
fn delete<R>(&mut self, f: impl FnOnce(Element::Mut<'_>) -> R) -> R;
}
impl<State, Action, Context, V, Element, Message>
ViewSequence<State, Action, Context, Element, Message> for V
impl<State, Action, Context, V, Element> ViewSequence<State, Action, Context, Element> for V
where
Context: ViewPathTracker,
V: View<State, Action, Context, Message> + ViewMarker,
V: View<State, Action, Context> + ViewMarker,
Element: SuperElement<V::Element, Context>,
V::Element: ViewElement,
{
@ -203,9 +202,9 @@ where
&self,
seq_state: &mut Self::SeqState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
self.message(seq_state, id_path, message, app_state)
}
}
@ -229,10 +228,10 @@ pub struct OptionSeqState<InnerState> {
///
/// Will mark messages which were sent to a `Some` value if a `None` has since
/// occurred as stale.
impl<State, Action, Context, Element, Seq, Message>
ViewSequence<State, Action, Context, Element, Message> for Option<Seq>
impl<State, Action, Context, Element, Seq> ViewSequence<State, Action, Context, Element>
for Option<Seq>
where
Seq: ViewSequence<State, Action, Context, Element, Message>,
Seq: ViewSequence<State, Action, Context, Element>,
Context: ViewPathTracker,
Element: ViewElement,
{
@ -345,9 +344,9 @@ where
&self,
seq_state: &mut Self::SeqState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let (start, rest) = id_path
.split_first()
.expect("Id path has elements for Option<ViewSequence>");
@ -410,10 +409,10 @@ fn view_id_to_index_generation(view_id: ViewId) -> (usize, u32) {
///
/// Will mark messages which were sent to any index as stale if
/// that index has been unused in the meantime.
impl<State, Action, Context, Element, Seq, Message>
ViewSequence<State, Action, Context, Element, Message> for Vec<Seq>
impl<State, Action, Context, Element, Seq> ViewSequence<State, Action, Context, Element>
for Vec<Seq>
where
Seq: ViewSequence<State, Action, Context, Element, Message>,
Seq: ViewSequence<State, Action, Context, Element>,
Context: ViewPathTracker,
Element: ViewElement,
{
@ -553,9 +552,9 @@ where
&self,
seq_state: &mut Self::SeqState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let (start, rest) = id_path
.split_first()
.expect("Id path has elements for Vec<ViewSequence>");
@ -571,10 +570,10 @@ where
}
}
impl<State, Action, Context, Element, Seq, Message, const N: usize>
ViewSequence<State, Action, Context, Element, Message> for [Seq; N]
impl<State, Action, Context, Element, Seq, const N: usize>
ViewSequence<State, Action, Context, Element> for [Seq; N]
where
Seq: ViewSequence<State, Action, Context, Element, Message>,
Seq: ViewSequence<State, Action, Context, Element>,
Context: ViewPathTracker,
Element: ViewElement,
{
@ -624,9 +623,9 @@ where
&self,
seq_state: &mut Self::SeqState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let (start, rest) = id_path
.split_first()
.expect("Id path has elements for [ViewSequence; N]");
@ -658,8 +657,7 @@ where
}
}
impl<State, Action, Context, Element, Message>
ViewSequence<State, Action, Context, Element, Message> for ()
impl<State, Action, Context, Element> ViewSequence<State, Action, Context, Element> for ()
where
Context: ViewPathTracker,
Element: ViewElement,
@ -697,18 +695,17 @@ where
&self,
_: &mut Self::SeqState,
_: &[ViewId],
_message: Message,
_message: DynMessage,
_: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
unreachable!("Messages should never be dispatched to an empty tuple");
// TODO add Debug trait bound because of this?: , got {message:?}
}
}
impl<State, Action, Context, Element, Seq, Message>
ViewSequence<State, Action, Context, Element, Message> for (Seq,)
impl<State, Action, Context, Element, Seq> ViewSequence<State, Action, Context, Element> for (Seq,)
where
Seq: ViewSequence<State, Action, Context, Element, Message>,
Seq: ViewSequence<State, Action, Context, Element>,
Context: ViewPathTracker,
Element: ViewElement,
{
@ -749,9 +746,9 @@ where
&self,
seq_state: &mut Self::SeqState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
self.0.seq_message(seq_state, id_path, message, app_state)
}
}
@ -767,9 +764,8 @@ macro_rules! impl_view_tuple {
Action,
Context: ViewPathTracker,
Element: ViewElement,
$($seq: ViewSequence<State, Action, Context, Element, Message>,)+
Message,
> ViewSequence<State, Action, Context, Element, Message> for ($($seq,)+)
$($seq: ViewSequence<State, Action, Context, Element>,)+
> ViewSequence<State, Action, Context, Element> for ($($seq,)+)
{
type SeqState = ($($seq::SeqState,)+);
@ -820,9 +816,9 @@ macro_rules! impl_view_tuple {
&self,
seq_state: &mut Self::SeqState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let (start, rest) = id_path
.split_first()
.expect("Id path has elements for tuple");
@ -883,9 +879,9 @@ impl ElementSplice<NoElement> for NoElements {
/// The [`ViewSequence`] for [`without_elements`], see its documentation for more context.
#[derive(Debug)]
pub struct WithoutElements<Seq, State, Action, Context, Message> {
pub struct WithoutElements<Seq, State, Action, Context> {
seq: Seq,
phantom: PhantomData<fn() -> (State, Action, Context, Message)>,
phantom: PhantomData<fn() -> (State, Action, Context)>,
}
/// An adapter which turns a [`ViewSequence`] containing any number of views with side effects, into a `ViewSequence` with any element type.
@ -908,15 +904,14 @@ pub struct WithoutElements<Seq, State, Action, Context, Message> {
///
/// # struct AppState;
/// ```
pub fn without_elements<State, Action, Context, Message, Seq>(
pub fn without_elements<State, Action, Context, Seq>(
seq: Seq,
) -> WithoutElements<Seq, State, Action, Context, Message>
) -> WithoutElements<Seq, State, Action, Context>
where
State: 'static,
Action: 'static,
Message: 'static,
Context: ViewPathTracker + 'static,
Seq: ViewSequence<State, Action, Context, NoElement, Message>,
Seq: ViewSequence<State, Action, Context, NoElement>,
{
WithoutElements {
seq,
@ -924,16 +919,14 @@ where
}
}
impl<State, Action, Context, Element, Message, Seq>
ViewSequence<State, Action, Context, Element, Message>
for WithoutElements<Seq, State, Action, Context, Message>
impl<State, Action, Context, Element, Seq> ViewSequence<State, Action, Context, Element>
for WithoutElements<Seq, State, Action, Context>
where
State: 'static,
Action: 'static,
Message: 'static,
Element: ViewElement,
Context: ViewPathTracker + 'static,
Seq: ViewSequence<State, Action, Context, NoElement, Message>,
Seq: ViewSequence<State, Action, Context, NoElement>,
{
type SeqState = Seq::SeqState;
@ -974,9 +967,9 @@ where
&self,
seq_state: &mut Self::SeqState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> crate::MessageResult<Action, Message> {
) -> crate::MessageResult<Action> {
self.seq.seq_message(seq_state, id_path, message, app_state)
}
}

View File

@ -58,11 +58,9 @@ pub trait ViewMarker {}
///
/// ## Alloc
///
/// In order to support the default open-ended [`DynMessage`] type as `Message`, this trait requires an
/// As it uses owned dynamically typed messages ([`DynMessage`]), this trait requires an
/// allocator to be available.
pub trait View<State, Action, Context: ViewPathTracker, Message = DynMessage>:
ViewMarker + 'static
{
pub trait View<State, Action, Context: ViewPathTracker>: ViewMarker + 'static {
/// The element type which this view operates on.
type Element: ViewElement;
/// State that is used over the lifetime of the retained representation of the view.
@ -105,9 +103,9 @@ pub trait View<State, Action, Context: ViewPathTracker, Message = DynMessage>:
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message>;
) -> MessageResult<Action>;
// fn debug_name?
}
@ -164,10 +162,10 @@ pub trait ViewPathTracker {
}
impl<V: ?Sized> ViewMarker for Box<V> {}
impl<State, Action, Context, Message, V> View<State, Action, Context, Message> for Box<V>
impl<State, Action, Context, V> View<State, Action, Context> for Box<V>
where
Context: ViewPathTracker,
V: View<State, Action, Context, Message> + ?Sized,
V: View<State, Action, Context> + ?Sized,
{
type Element = V::Element;
type ViewState = V::ViewState;
@ -202,9 +200,9 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
self.deref()
.message(view_state, id_path, message, app_state)
}
@ -223,10 +221,10 @@ pub struct RcState<ViewState> {
impl<V: ?Sized> ViewMarker for Arc<V> {}
/// An implementation of [`View`] which only runs rebuild if the states are different
impl<State, Action, Context, Message, V> View<State, Action, Context, Message> for Arc<V>
impl<State, Action, Context, V> View<State, Action, Context> for Arc<V>
where
Context: ViewPathTracker,
V: View<State, Action, Context, Message> + ?Sized,
V: View<State, Action, Context> + ?Sized,
{
type Element = V::Element;
type ViewState = RcState<V::ViewState>;
@ -272,9 +270,9 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let message_result =
self.deref()
.message(&mut view_state.view_state, id_path, message, app_state);
@ -287,10 +285,10 @@ where
impl<V: ?Sized> ViewMarker for Rc<V> {}
/// An implementation of [`View`] which only runs rebuild if the states are different
impl<State, Action, Context, Message, V> View<State, Action, Context, Message> for Rc<V>
impl<State, Action, Context, V> View<State, Action, Context> for Rc<V>
where
Context: ViewPathTracker,
V: View<State, Action, Context, Message> + ?Sized,
V: View<State, Action, Context> + ?Sized,
{
type Element = V::Element;
type ViewState = RcState<V::ViewState>;
@ -336,9 +334,9 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let message_result =
self.deref()
.message(&mut view_state.view_state, id_path, message, app_state);

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::{
AppendVec, Mut, NoElement, View, ViewId, ViewMarker, ViewPathTracker, ViewSequence,
AppendVec, DynMessage, Mut, NoElement, View, ViewId, ViewMarker, ViewPathTracker, ViewSequence,
sequence::NoElements,
};
@ -28,11 +28,11 @@ pub struct Fork<Active, Alongside> {
}
impl<Active, Alongside> ViewMarker for Fork<Active, Alongside> {}
impl<State, Action, Context, Active, Alongside, Message> View<State, Action, Context, Message>
impl<State, Action, Context, Active, Alongside> View<State, Action, Context>
for Fork<Active, Alongside>
where
Active: View<State, Action, Context, Message>,
Alongside: ViewSequence<State, Action, Context, NoElement, Message>,
Active: View<State, Action, Context>,
Alongside: ViewSequence<State, Action, Context, NoElement>,
Context: ViewPathTracker,
{
type Element = Active::Element;
@ -93,9 +93,9 @@ where
&self,
(active_state, alongside_state): &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> crate::MessageResult<Action, Message> {
) -> crate::MessageResult<Action> {
let (first, id_path) = id_path
.split_first()
.expect("Id path has elements for Fork");

View File

@ -5,20 +5,20 @@ use core::any::type_name;
use core::fmt::Debug;
use core::marker::PhantomData;
use crate::{MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
use crate::{DynMessage, MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
/// The View for [`lens`].
///
/// See its documentation for more context.
#[must_use = "View values do nothing unless provided to Xilem."]
pub struct Lens<CF, V, F, ParentState, ChildState, Action, Context, Message> {
pub struct Lens<CF, V, F, ParentState, ChildState, Action, Context> {
access_state: F,
child_component: CF,
phantom: PhantomData<fn(ParentState) -> (ChildState, Action, Context, Message, V)>,
phantom: PhantomData<fn(ParentState) -> (ChildState, Action, Context, V)>,
}
impl<CF, V, F, ParentState, ChildState, Action, Context, Message> Debug
for Lens<CF, V, F, ParentState, ChildState, Action, Context, Message>
impl<CF, V, F, ParentState, ChildState, Action, Context> Debug
for Lens<CF, V, F, ParentState, ChildState, Action, Context>
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Lens")
@ -67,16 +67,16 @@ impl<CF, V, F, ParentState, ChildState, Action, Context, Message> Debug
/// available_flights: Vec<Flight>,
/// }
/// ```
pub fn lens<OuterState, Action, Context, Message, InnerState, StateF, InnerView, Component>(
pub fn lens<OuterState, Action, Context, InnerState, StateF, InnerView, Component>(
component: Component,
// This parameter ordering does run into https://github.com/rust-lang/rustfmt/issues/3605
// Our general advice is to make sure that the lens arguments are short enough...
access_state: StateF,
) -> Lens<Component, InnerView, StateF, OuterState, InnerState, Action, Context, Message>
) -> Lens<Component, InnerView, StateF, OuterState, InnerState, Action, Context>
where
StateF: Fn(&mut OuterState) -> &mut InnerState + Send + Sync + 'static,
Component: Fn(&mut InnerState) -> InnerView,
InnerView: View<InnerState, Action, Context, Message>,
InnerView: View<InnerState, Action, Context>,
Context: ViewPathTracker,
{
Lens {
@ -86,22 +86,21 @@ where
}
}
impl<Component, V, StateF, ParentState, ChildState, Action, Context, Message> ViewMarker
for Lens<Component, V, StateF, ParentState, ChildState, Action, Context, Message>
impl<Component, V, StateF, ParentState, ChildState, Action, Context> ViewMarker
for Lens<Component, V, StateF, ParentState, ChildState, Action, Context>
{
}
impl<Component, ParentState, ChildState, Action, Context, Message, V, StateF>
View<ParentState, Action, Context, Message>
for Lens<Component, V, StateF, ParentState, ChildState, Action, Context, Message>
impl<Component, ParentState, ChildState, Action, Context, V, StateF>
View<ParentState, Action, Context>
for Lens<Component, V, StateF, ParentState, ChildState, Action, Context>
where
ParentState: 'static,
ChildState: 'static,
V: View<ChildState, Action, Context, Message>,
V: View<ChildState, Action, Context>,
Component: Fn(&mut ChildState) -> V + 'static,
StateF: Fn(&mut ParentState) -> &mut ChildState + 'static,
Action: 'static,
Context: ViewPathTracker + 'static,
Message: 'static,
{
type ViewState = (V, V::ViewState);
type Element = V::Element;
@ -146,9 +145,9 @@ where
&self,
(child, child_view_state): &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut ParentState,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
child.message(
child_view_state,
id_path,

View File

@ -4,7 +4,7 @@
use core::fmt::Debug;
use core::marker::PhantomData;
use crate::{MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
use crate::{DynMessage, MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
/// View type for [`map_message`] and [`map_action`]. Most users will want to use `map_action` (the latter).
///
@ -16,17 +16,16 @@ pub struct MapMessage<
ParentAction,
ChildAction,
Context,
Message,
// This default only exists for documentation purposes.
F = fn(&mut State, ChildAction) -> ParentAction,
> {
map_fn: F,
child: V,
phantom: PhantomData<fn() -> (State, ParentAction, ChildAction, Context, Message)>,
phantom: PhantomData<fn() -> (State, ParentAction, ChildAction, Context)>,
}
impl<V, State, ParentAction, ChildAction, Context, Message, F> Debug
for MapMessage<V, State, ParentAction, ChildAction, Context, Message, F>
impl<V, State, ParentAction, ChildAction, Context, F> Debug
for MapMessage<V, State, ParentAction, ChildAction, Context, F>
where
V: Debug,
{
@ -66,7 +65,7 @@ where
/// })
/// }
/// ```
pub fn map_action<State, ParentAction, ChildAction, Context: ViewPathTracker, Message, V, F>(
pub fn map_action<State, ParentAction, ChildAction, Context: ViewPathTracker, V, F>(
view: V,
map_fn: F,
) -> MapMessage<
@ -75,19 +74,17 @@ pub fn map_action<State, ParentAction, ChildAction, Context: ViewPathTracker, Me
ParentAction,
ChildAction,
Context,
Message,
impl Fn(&mut State, MessageResult<ChildAction, Message>) -> MessageResult<ParentAction, Message>
+ 'static,
impl Fn(&mut State, MessageResult<ChildAction>) -> MessageResult<ParentAction> + 'static,
>
where
State: 'static,
ParentAction: 'static,
ChildAction: 'static,
V: View<State, ChildAction, Context, Message>,
V: View<State, ChildAction, Context>,
F: Fn(&mut State, ChildAction) -> ParentAction + 'static,
{
MapMessage {
map_fn: move |app_state: &mut State, result: MessageResult<ChildAction, Message>| {
map_fn: move |app_state: &mut State, result: MessageResult<ChildAction>| {
result.map(|action| map_fn(app_state, action))
},
child: view,
@ -99,17 +96,16 @@ where
///
/// This is the more general form of [`map_action`].
/// In most cases, you probably want to use that function.
pub fn map_message<State, ParentAction, ChildAction, Context: ViewPathTracker, Message, V, F>(
pub fn map_message<State, ParentAction, ChildAction, Context: ViewPathTracker, V, F>(
view: V,
map_fn: F,
) -> MapMessage<V, State, ParentAction, ChildAction, Context, Message, F>
) -> MapMessage<V, State, ParentAction, ChildAction, Context, F>
where
State: 'static,
ParentAction: 'static,
ChildAction: 'static,
V: View<State, ChildAction, Context, Message>,
F: Fn(&mut State, MessageResult<ChildAction, Message>) -> MessageResult<ParentAction, Message>
+ 'static,
V: View<State, ChildAction, Context>,
F: Fn(&mut State, MessageResult<ChildAction>) -> MessageResult<ParentAction> + 'static,
{
MapMessage {
map_fn,
@ -118,22 +114,19 @@ where
}
}
impl<V, State, ParentAction, ChildAction, F, Context, Message> ViewMarker
for MapMessage<V, State, ParentAction, ChildAction, Context, Message, F>
impl<V, State, ParentAction, ChildAction, F, Context> ViewMarker
for MapMessage<V, State, ParentAction, ChildAction, Context, F>
{
}
impl<V, State, ParentAction, ChildAction, Context, Message, F>
View<State, ParentAction, Context, Message>
for MapMessage<V, State, ParentAction, ChildAction, Context, Message, F>
impl<V, State, ParentAction, ChildAction, Context, F> View<State, ParentAction, Context>
for MapMessage<V, State, ParentAction, ChildAction, Context, F>
where
V: View<State, ChildAction, Context, Message>,
V: View<State, ChildAction, Context>,
State: 'static,
ParentAction: 'static,
ChildAction: 'static,
F: Fn(&mut State, MessageResult<ChildAction, Message>) -> MessageResult<ParentAction, Message>
+ 'static,
F: Fn(&mut State, MessageResult<ChildAction>) -> MessageResult<ParentAction> + 'static,
Context: ViewPathTracker + 'static,
Message: 'static,
{
type ViewState = V::ViewState;
type Element = V::Element;
@ -168,9 +161,9 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<ParentAction, Message> {
) -> MessageResult<ParentAction> {
let child_result = self.child.message(view_state, id_path, message, app_state);
(self.map_fn)(app_state, child_result)
}

View File

@ -4,20 +4,20 @@
use core::fmt::Debug;
use core::marker::PhantomData;
use crate::{MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
use crate::{DynMessage, MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
/// The View for [`map_state`].
///
/// See its documentation for more context.
#[must_use = "View values do nothing unless provided to Xilem."]
pub struct MapState<V, F, ParentState, ChildState, Action, Context, Message> {
pub struct MapState<V, F, ParentState, ChildState, Action, Context> {
map_state: F,
child: V,
phantom: PhantomData<fn(ParentState) -> (ChildState, Action, Context, Message)>,
phantom: PhantomData<fn(ParentState) -> (ChildState, Action, Context)>,
}
impl<V, F, ParentState, ChildState, Action, Context, Message> Debug
for MapState<V, F, ParentState, ChildState, Action, Context, Message>
impl<V, F, ParentState, ChildState, Action, Context> Debug
for MapState<V, F, ParentState, ChildState, Action, Context>
where
V: Debug,
{
@ -56,14 +56,14 @@ where
/// map_state(count_view(state.count), |state: &mut AppState| &mut state.count)
/// }
/// ```
pub fn map_state<ParentState, ChildState, Action, Context: ViewPathTracker, Message, V, F>(
pub fn map_state<ParentState, ChildState, Action, Context: ViewPathTracker, V, F>(
view: V,
f: F,
) -> MapState<V, F, ParentState, ChildState, Action, Context, Message>
) -> MapState<V, F, ParentState, ChildState, Action, Context>
where
ParentState: 'static,
ChildState: 'static,
V: View<ChildState, Action, Context, Message>,
V: View<ChildState, Action, Context>,
F: Fn(&mut ParentState) -> &mut ChildState + 'static,
{
MapState {
@ -73,21 +73,19 @@ where
}
}
impl<V, F, ParentState, ChildState, Action, Context, Message> ViewMarker
for MapState<V, F, ParentState, ChildState, Action, Context, Message>
impl<V, F, ParentState, ChildState, Action, Context> ViewMarker
for MapState<V, F, ParentState, ChildState, Action, Context>
{
}
impl<ParentState, ChildState, Action, Context, Message, V, F>
View<ParentState, Action, Context, Message>
for MapState<V, F, ParentState, ChildState, Action, Context, Message>
impl<ParentState, ChildState, Action, Context, V, F> View<ParentState, Action, Context>
for MapState<V, F, ParentState, ChildState, Action, Context>
where
ParentState: 'static,
ChildState: 'static,
V: View<ChildState, Action, Context, Message>,
V: View<ChildState, Action, Context>,
F: Fn(&mut ParentState) -> &mut ChildState + 'static,
Action: 'static,
Context: ViewPathTracker + 'static,
Message: 'static,
{
type ViewState = V::ViewState;
type Element = V::Element;
@ -132,9 +130,9 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut ParentState,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
self.child
.message(view_state, id_path, message, (self.map_state)(app_state))
}

View File

@ -5,21 +5,21 @@ use core::fmt::Debug;
use core::marker::PhantomData;
use core::mem::size_of;
use crate::{MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
use crate::{DynMessage, MessageResult, Mut, View, ViewId, ViewMarker, ViewPathTracker};
/// A view which supports Memoization.
///
/// The story of Memoization in Xilem is still being worked out,
/// so the details of this view might change.
#[must_use = "View values do nothing unless provided to Xilem."]
pub struct Memoize<Data, InitView, State, Action, Context, Message> {
pub struct Memoize<Data, InitView, State, Action, Context> {
data: Data,
init_view: InitView,
phantom: PhantomData<fn() -> (State, Action, Context, Message)>,
phantom: PhantomData<fn() -> (State, Action, Context)>,
}
impl<Data, InitView, State, Action, Context, Message> Debug
for Memoize<Data, InitView, State, Action, Context, Message>
impl<Data, InitView, State, Action, Context> Debug
for Memoize<Data, InitView, State, Action, Context>
where
Data: Debug,
{
@ -52,15 +52,15 @@ It's not possible in Rust currently to check whether the (content of the) callba
/// )
/// }
/// ```
pub fn memoize<State, Action, Context, Message, Data, V, InitView>(
pub fn memoize<State, Action, Context, Data, V, InitView>(
data: Data,
init_view: InitView,
) -> Memoize<Data, InitView, State, Action, Context, Message>
) -> Memoize<Data, InitView, State, Action, Context>
where
Data: PartialEq + 'static,
// TODO(DJMcNab): Also accept `&mut State` in this argument closure
InitView: Fn(&Data) -> V + 'static,
V: View<State, Action, Context, Message>,
V: View<State, Action, Context>,
Context: ViewPathTracker,
{
const {
@ -81,19 +81,18 @@ pub struct MemoizeState<V, VState> {
dirty: bool,
}
impl<Data, ViewFn, State, Action, Context, Message> ViewMarker
for Memoize<Data, ViewFn, State, Action, Context, Message>
impl<Data, ViewFn, State, Action, Context> ViewMarker
for Memoize<Data, ViewFn, State, Action, Context>
{
}
impl<State, Action, Context, Data, V, ViewFn, Message> View<State, Action, Context, Message>
for Memoize<Data, ViewFn, State, Action, Context, Message>
impl<State, Action, Context, Data, V, ViewFn> View<State, Action, Context>
for Memoize<Data, ViewFn, State, Action, Context>
where
State: 'static,
Action: 'static,
Context: ViewPathTracker + 'static,
Message: 'static,
Data: PartialEq + 'static,
V: View<State, Action, Context, Message>,
V: View<State, Action, Context>,
ViewFn: Fn(&Data) -> V + 'static,
{
type ViewState = MemoizeState<V, V::ViewState>;
@ -136,9 +135,9 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let message_result =
view_state
.view
@ -186,14 +185,14 @@ impl<InitView, State, Action> Debug for Frozen<InitView, State, Action> {
/// frozen(|| button("doesn't access any external state", |count| { count += 1; })),
/// }
/// ```
pub fn frozen<State, Action, Context, Message, V, InitView>(
pub fn frozen<State, Action, Context, V, InitView>(
init_view: InitView,
) -> Frozen<InitView, State, Action>
where
State: 'static,
Action: 'static,
Context: ViewPathTracker,
V: View<State, Action, Context, Message>,
V: View<State, Action, Context>,
InitView: Fn() -> V,
{
const {
@ -206,13 +205,13 @@ where
}
impl<InitView, State, Action> ViewMarker for Frozen<InitView, State, Action> {}
impl<State, Action, Context, Message, V, InitView> View<State, Action, Context, Message>
impl<State, Action, Context, V, InitView> View<State, Action, Context>
for Frozen<InitView, State, Action>
where
State: 'static,
Action: 'static,
Context: ViewPathTracker,
V: View<State, Action, Context, Message>,
V: View<State, Action, Context>,
InitView: Fn() -> V + 'static,
{
type Element = V::Element;
@ -267,9 +266,9 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let message_result =
view_state
.view

View File

@ -5,7 +5,9 @@
use hidden::OneOfState;
use crate::{MessageResult, Mut, View, ViewElement, ViewId, ViewMarker, ViewPathTracker};
use crate::{
DynMessage, MessageResult, Mut, View, ViewElement, ViewId, ViewMarker, ViewPathTracker,
};
/// This trait allows, specifying a type as `ViewElement`, which should never be constructed or used.
///
@ -182,8 +184,8 @@ pub trait OneOfCtx<
impl<A, B, C, D, E, F, G, H, I> ViewMarker for OneOf<A, B, C, D, E, F, G, H, I> {}
/// The `OneOf` types and `Either` are [`View`]s if all of their possible types are themselves `View`s.
impl<State, Action, Context, Message, A, B, C, D, E, F, G, H, I>
View<State, Action, Context, Message> for OneOf<A, B, C, D, E, F, G, H, I>
impl<State, Action, Context, A, B, C, D, E, F, G, H, I> View<State, Action, Context>
for OneOf<A, B, C, D, E, F, G, H, I>
where
State: 'static,
Action: 'static,
@ -199,15 +201,15 @@ where
H::Element,
I::Element,
>,
A: View<State, Action, Context, Message>,
B: View<State, Action, Context, Message>,
C: View<State, Action, Context, Message>,
D: View<State, Action, Context, Message>,
E: View<State, Action, Context, Message>,
F: View<State, Action, Context, Message>,
G: View<State, Action, Context, Message>,
H: View<State, Action, Context, Message>,
I: View<State, Action, Context, Message>,
A: View<State, Action, Context>,
B: View<State, Action, Context>,
C: View<State, Action, Context>,
D: View<State, Action, Context>,
E: View<State, Action, Context>,
F: View<State, Action, Context>,
G: View<State, Action, Context>,
H: View<State, Action, Context>,
I: View<State, Action, Context>,
{
#[doc(hidden)]
type Element = Context::OneOfElement;
@ -525,9 +527,9 @@ where
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
let (start, rest) = id_path
.split_first()
.expect("Id path has elements for OneOf");
@ -554,16 +556,14 @@ where
#[doc(hidden)]
mod hidden {
use super::PhantomElementCtx;
use crate::{View, ViewMarker};
use crate::{DynMessage, View, ViewMarker};
#[allow(unnameable_types)] // reason: Implementation detail, public because of trait visibility rules
#[derive(Debug)]
pub enum Never {}
impl ViewMarker for Never {}
impl<State, Action, Context: PhantomElementCtx, Message> View<State, Action, Context, Message>
for Never
{
impl<State, Action, Context: PhantomElementCtx> View<State, Action, Context> for Never {
type Element = Context::PhantomElement;
type ViewState = Self;
@ -597,9 +597,9 @@ mod hidden {
&self,
_: &mut Self::ViewState,
_: &[crate::ViewId],
_: Message,
_: DynMessage,
_: &mut State,
) -> crate::MessageResult<Action, Message> {
) -> crate::MessageResult<Action> {
match *self {}
}
}

View File

@ -8,7 +8,7 @@ use crate::{
/// This trait provides a way to add [`View`] implementations for types that would be restricted otherwise by the orphan rules.
///
/// Every type that can be supported with this trait, needs a concrete `View` implementation in `xilem_core`, possibly feature-gated.
pub trait OrphanView<V, State, Action, Message = DynMessage>: ViewPathTracker + Sized {
pub trait OrphanView<V, State, Action>: ViewPathTracker + Sized {
/// See [`View::Element`]
type OrphanElement: ViewElement;
/// See [`View::ViewState`]
@ -45,18 +45,18 @@ pub trait OrphanView<V, State, Action, Message = DynMessage>: ViewPathTracker +
view: &V,
view_state: &mut Self::OrphanViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message>;
) -> MessageResult<Action>;
}
macro_rules! impl_orphan_view_for {
($ty: ty) => {
impl ViewMarker for $ty {}
impl<State, Action, Context, Message> View<State, Action, Context, Message> for $ty
impl<State, Action, Context> View<State, Action, Context> for $ty
where
Context: OrphanView<$ty, State, Action, Message>,
Context: OrphanView<$ty, State, Action>,
{
type Element = Context::OrphanElement;
@ -95,9 +95,9 @@ macro_rules! impl_orphan_view_for {
&self,
view_state: &mut Self::ViewState,
id_path: &[ViewId],
message: Message,
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
Context::orphan_message(self, view_state, id_path, message, app_state)
}
}
@ -128,7 +128,7 @@ impl_orphan_view_for!(usize);
/// These [`OrphanView`] implementations can e.g. be used in a vector graphics context, as for example seen in `xilem_web` within svg nodes
mod kurbo {
use super::OrphanView;
use crate::{MessageResult, Mut, View, ViewId, ViewMarker};
use crate::{DynMessage, MessageResult, Mut, View, ViewId, ViewMarker};
impl_orphan_view_for!(kurbo::PathSeg);
impl_orphan_view_for!(kurbo::Arc);
impl_orphan_view_for!(kurbo::BezPath);

View File

@ -3,7 +3,7 @@
use core::fmt::Debug;
use crate::{MessageResult, NoElement, View, ViewMarker, ViewPathTracker};
use crate::{DynMessage, MessageResult, NoElement, View, ViewMarker, ViewPathTracker};
/// A view which executes `once` exactly once.
///
@ -84,12 +84,10 @@ impl<F> Debug for RunOnce<F> {
}
impl<F> ViewMarker for RunOnce<F> {}
impl<F, State, Action, Context, Message> View<State, Action, Context, Message> for RunOnce<F>
impl<F, State, Action, Context> View<State, Action, Context> for RunOnce<F>
where
Context: ViewPathTracker,
F: Fn() + 'static,
// TODO: Work out what traits we want to require `Message`s to have
Message: Debug,
{
type Element = NoElement;
@ -125,9 +123,9 @@ where
&self,
(): &mut Self::ViewState,
_: &[crate::ViewId],
message: Message,
message: DynMessage,
_: &mut State,
) -> MessageResult<Action, Message> {
) -> MessageResult<Action> {
// Nothing to do
panic!("Message should not have been sent to a `RunOnce` View: {message:?}");
}

View File

@ -74,7 +74,7 @@ impl<State, Action> OrphanView<&'static str, State, Action> for TestCtx {
_id_path: &[ViewId],
message: DynMessage,
_app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
MessageResult::Stale(message)
}
}

View File

@ -105,8 +105,7 @@ impl<State, Action, E, F> ViewMarker for AfterBuild<State, Action, E, F> {}
impl<State, Action, E, F> ViewMarker for AfterRebuild<State, Action, E, F> {}
impl<State, Action, E, F> ViewMarker for BeforeTeardown<State, Action, E, F> {}
impl<State, Action, V, F> View<State, Action, ViewCtx, DynMessage>
for AfterBuild<State, Action, V, F>
impl<State, Action, V, F> View<State, Action, ViewCtx> for AfterBuild<State, Action, V, F>
where
State: 'static,
Action: 'static,
@ -152,14 +151,13 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.element
.message(view_state, id_path, message, app_state)
}
}
impl<State, Action, V, F> View<State, Action, ViewCtx, DynMessage>
for AfterRebuild<State, Action, V, F>
impl<State, Action, V, F> View<State, Action, ViewCtx> for AfterRebuild<State, Action, V, F>
where
State: 'static,
Action: 'static,
@ -209,14 +207,13 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.element
.message(view_state, id_path, message, app_state)
}
}
impl<State, Action, V, F> View<State, Action, ViewCtx, DynMessage>
for BeforeTeardown<State, Action, V, F>
impl<State, Action, V, F> View<State, Action, ViewCtx> for BeforeTeardown<State, Action, V, F>
where
State: 'static,
Action: 'static,
@ -260,7 +257,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.element
.message(view_state, id_path, message, app_state)
}

View File

@ -91,8 +91,7 @@ fn clear_interval(handle: i32) {
impl<Callback, State, Action> ViewMarker for Interval<Callback, State, Action> {}
impl<State, Action, Callback, OA> View<State, Action, ViewCtx, DynMessage>
for Interval<Callback, State, Action>
impl<State, Action, Callback, OA> View<State, Action, ViewCtx> for Interval<Callback, State, Action>
where
State: 'static,
Action: 'static,
@ -144,7 +143,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
debug_assert!(id_path.is_empty());
message.downcast::<()>().unwrap_throw();
match (self.callback)(app_state).action() {

View File

@ -162,7 +162,7 @@ impl<State, Action, OA, InitFuture, Data, CB, F, FOut> ViewMarker
for MemoizedAwait<State, Action, OA, InitFuture, Data, CB, F, FOut>
{
}
impl<State, Action, InitFuture, F, FOut, Data, CB, OA> View<State, Action, ViewCtx, DynMessage>
impl<State, Action, InitFuture, F, FOut, Data, CB, OA> View<State, Action, ViewCtx>
for MemoizedAwait<State, Action, OA, InitFuture, Data, CB, F, FOut>
where
State: 'static,
@ -248,7 +248,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
assert_eq!(id_path.len(), 1);
if id_path[0].routing_id() == view_state.generation {
match *message.downcast().unwrap_throw() {

View File

@ -131,7 +131,7 @@ impl TaskProxy {
impl<F, H, M> ViewMarker for Task<F, H, M> {}
impl<State, Action, F, H, M, Fut> View<State, Action, ViewCtx, DynMessage> for Task<F, H, M>
impl<State, Action, F, H, M, Fut> View<State, Action, ViewCtx> for Task<F, H, M>
where
State: 'static,
Action: 'static,
@ -185,7 +185,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
debug_assert!(
id_path.is_empty(),
"id path should be empty in AsyncRepeat::message"

View File

@ -62,7 +62,7 @@ pub(crate) trait DomViewSequence<State, Action>: 'static {
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage>;
) -> MessageResult<Action>;
}
impl<State, Action, S> DomViewSequence<State, Action> for S
@ -122,7 +122,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.seq_message(
seq_state.downcast_mut().unwrap_throw(),
id_path,
@ -359,7 +359,7 @@ where
}
}
impl<State, Action, Children> ViewMarker for CustomElement<Children, State, Action> {}
impl<State, Action, Children> View<State, Action, ViewCtx, DynMessage>
impl<State, Action, Children> View<State, Action, ViewCtx>
for CustomElement<Children, State, Action>
where
Children: 'static,
@ -424,7 +424,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.children
.dyn_seq_message(&mut view_state.seq_state, id_path, message, app_state)
}
@ -453,7 +453,7 @@ macro_rules! define_element {
}
impl<Children, State, Action> ViewMarker for $ty_name<Children, State, Action> {}
impl<Children, State, Action> View<State, Action, ViewCtx, DynMessage>
impl<Children, State, Action> View<State, Action, ViewCtx>
for $ty_name<Children, State, Action>
where
Children: 'static,
@ -506,7 +506,7 @@ macro_rules! define_element {
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.children.dyn_seq_message(
&mut view_state.seq_state,
id_path,

View File

@ -220,7 +220,7 @@ fn message_event_listener<State, Action, V, Event, OA, Callback>(
message: DynMessage,
app_state: &mut State,
handler: &Callback,
) -> MessageResult<Action, DynMessage>
) -> MessageResult<Action>
where
State: 'static,
Action: 'static,
@ -247,7 +247,7 @@ where
}
impl<V, State, Action, Event, Callback> ViewMarker for OnEvent<V, State, Action, Event, Callback> {}
impl<V, State, Action, Event, Callback, OA> View<State, Action, ViewCtx, DynMessage>
impl<V, State, Action, Event, Callback, OA> View<State, Action, ViewCtx>
for OnEvent<V, State, Action, Event, Callback>
where
State: 'static,
@ -341,7 +341,7 @@ where
id_path: &[ViewId],
message: crate::DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
message_event_listener(
&self.dom_view,
view_state,
@ -400,7 +400,7 @@ macro_rules! event_definitions {
}
impl<V, State, Action, Callback, OA> View<State, Action, ViewCtx, DynMessage>
impl<V, State, Action, Callback, OA> View<State, Action, ViewCtx>
for $ty_name<V, State, Action, Callback>
where
State: 'static,
@ -463,7 +463,7 @@ macro_rules! event_definitions {
id_path: &[ViewId],
message: crate::DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
message_event_listener(&self.dom_view, view_state, id_path, message, app_state, &self.handler)
}
}
@ -571,8 +571,8 @@ pub struct OnResizeState<VState> {
}
impl<V, State, Action, Callback> ViewMarker for OnResize<V, State, Action, Callback> {}
impl<State, Action, OA, Callback, V: View<State, Action, ViewCtx, DynMessage>>
View<State, Action, ViewCtx, DynMessage> for OnResize<V, State, Action, Callback>
impl<State, Action, OA, Callback, V: View<State, Action, ViewCtx>> View<State, Action, ViewCtx>
for OnResize<V, State, Action, Callback>
where
State: 'static,
Action: 'static,
@ -650,7 +650,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
let Some((first, remainder)) = id_path.split_first() else {
throw_str("Parent view of `OnResize` sent outdated and/or incorrect empty view path");
};

View File

@ -108,11 +108,11 @@ pub trait DomNode: AnyNode {
}
/// A view which can have any [`DomView`] type, see [`AnyView`] for more details.
pub type AnyDomView<State, Action = ()> = dyn AnyView<State, Action, ViewCtx, AnyPod, DynMessage>;
pub type AnyDomView<State, Action = ()> = dyn AnyView<State, Action, ViewCtx, AnyPod>;
/// The central [`View`] derived trait to represent DOM nodes in `xilem_web`, it's the base for all [`View`]s in `xilem_web`
pub trait DomView<State, Action = ()>:
View<State, Action, ViewCtx, DynMessage, Element = Pod<Self::DomNode>>
View<State, Action, ViewCtx, Element = Pod<Self::DomNode>>
{
type DomNode: DomNode;
@ -172,7 +172,7 @@ pub trait DomView<State, Action = ()>:
fn map_state<ParentState, F>(
self,
f: F,
) -> MapState<Self, F, ParentState, State, Action, ViewCtx, DynMessage>
) -> MapState<Self, F, ParentState, State, Action, ViewCtx>
where
State: 'static,
ParentState: 'static,
@ -192,12 +192,7 @@ pub trait DomView<State, Action = ()>:
ParentAction,
Action,
ViewCtx,
DynMessage,
impl Fn(
&mut State,
MessageResult<Action, DynMessage>,
) -> MessageResult<ParentAction, DynMessage>
+ 'static,
impl Fn(&mut State, MessageResult<Action>) -> MessageResult<ParentAction> + 'static,
>
where
State: 'static,
@ -212,7 +207,7 @@ pub trait DomView<State, Action = ()>:
impl<V, State, Action, N> DomView<State, Action> for V
where
V: View<State, Action, ViewCtx, DynMessage, Element = Pod<N>>,
V: View<State, Action, ViewCtx, Element = Pod<N>>,
N: DomNode,
{
type DomNode = N;
@ -228,13 +223,10 @@ where
/// (clicks >= 5).then_some("Huzzah, clicked at least 5 times")
/// }
/// ```
pub trait DomFragment<State, Action = ()>:
ViewSequence<State, Action, ViewCtx, AnyPod, DynMessage>
{
}
pub trait DomFragment<State, Action = ()>: ViewSequence<State, Action, ViewCtx, AnyPod> {}
impl<V, State, Action> DomFragment<State, Action> for V where
V: ViewSequence<State, Action, ViewCtx, AnyPod, DynMessage>
V: ViewSequence<State, Action, ViewCtx, AnyPod>
{
}

View File

@ -298,7 +298,7 @@ impl<V, State, Action> Attr<V, State, Action> {
}
impl<V, State, Action> ViewMarker for Attr<V, State, Action> {}
impl<V, State, Action> View<State, Action, ViewCtx, DynMessage> for Attr<V, State, Action>
impl<V, State, Action> View<State, Action, ViewCtx> for Attr<V, State, Action>
where
State: 'static,
Action: 'static,
@ -352,7 +352,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.inner.message(view_state, id_path, message, app_state)
}
}

View File

@ -333,7 +333,7 @@ impl<E, C, T, A> Class<E, C, T, A> {
}
impl<V, C, State, Action> ViewMarker for Class<V, C, State, Action> {}
impl<V, C, State, Action> View<State, Action, ViewCtx, DynMessage> for Class<V, C, State, Action>
impl<V, C, State, Action> View<State, Action, ViewCtx> for Class<V, C, State, Action>
where
State: 'static,
Action: 'static,
@ -390,7 +390,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.el.message(view_state, id_path, message, app_state)
}
}

View File

@ -177,8 +177,7 @@ macro_rules! overwrite_bool_modifier_view {
}
impl<V, State, Action> $crate::core::ViewMarker for $modifier<V, State, Action> {}
impl<V, State, Action>
$crate::core::View<State, Action, $crate::ViewCtx, $crate::DynMessage>
impl<V, State, Action> $crate::core::View<State, Action, $crate::ViewCtx>
for $modifier<V, State, Action>
where
State: 'static,
@ -244,7 +243,7 @@ macro_rules! overwrite_bool_modifier_view {
id_path: &[$crate::core::ViewId],
message: $crate::DynMessage,
app_state: &mut State,
) -> $crate::core::MessageResult<Action, $crate::DynMessage> {
) -> $crate::core::MessageResult<Action> {
self.inner.message(view_state, id_path, message, app_state)
}
}

View File

@ -458,7 +458,7 @@ impl<E, S, T, A> Style<E, S, T, A> {
}
impl<E, S, State, Action> ViewMarker for Style<E, S, State, Action> {}
impl<V, S, State, Action> View<State, Action, ViewCtx, DynMessage> for Style<V, S, State, Action>
impl<V, S, State, Action> View<State, Action, ViewCtx> for Style<V, S, State, Action>
where
State: 'static,
Action: 'static,
@ -511,7 +511,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.el.message(view_state, id_path, message, app_state)
}
}
@ -547,7 +547,7 @@ fn rotate_transform_modifier(transform: Option<&CowStr>, radians: &f64) -> Style
}
impl<V, State, Action> ViewMarker for Rotate<V, State, Action> {}
impl<V, State, Action> View<State, Action, ViewCtx, DynMessage> for Rotate<V, State, Action>
impl<V, State, Action> View<State, Action, ViewCtx> for Rotate<V, State, Action>
where
State: 'static,
Action: 'static,
@ -607,7 +607,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.el.message(view_state, id_path, message, app_state)
}
}
@ -673,7 +673,7 @@ fn scale_transform_modifier(transform: Option<&CowStr>, scale: &ScaleValue) -> S
}
impl<E, State, Action> ViewMarker for Scale<E, State, Action> {}
impl<State, Action, V> View<State, Action, ViewCtx, DynMessage> for Scale<V, State, Action>
impl<State, Action, V> View<State, Action, ViewCtx> for Scale<V, State, Action>
where
State: 'static,
Action: 'static,
@ -733,7 +733,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.el.message(view_state, id_path, message, app_state)
}
}

View File

@ -133,7 +133,7 @@ fn build_event_listeners(
}
impl<V, State, Action, Callback> ViewMarker for Pointer<V, State, Action, Callback> {}
impl<State, Action, Callback, V> View<State, Action, ViewCtx, DynMessage>
impl<State, Action, Callback, V> View<State, Action, ViewCtx>
for Pointer<V, State, Action, Callback>
where
State: 'static,
@ -204,7 +204,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
let Some((first, remainder)) = id_path.split_first() else {
throw_str("Parent view of `Pointer` sent outdated and/or incorrect empty view path");
};

View File

@ -95,7 +95,7 @@ fn opacity_attr_modifier(attr: &'static str, brush: &Brush) -> AttributeModifier
}
impl<V, State, Action> ViewMarker for Fill<V, State, Action> {}
impl<State, Action, V> View<State, Action, ViewCtx, DynMessage> for Fill<V, State, Action>
impl<State, Action, V> View<State, Action, ViewCtx> for Fill<V, State, Action>
where
State: 'static,
Action: 'static,
@ -169,7 +169,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.child.message(child_state, id_path, message, app_state)
}
}
@ -239,7 +239,7 @@ fn update_stroke_modifiers(
}
impl<V, State, Action> ViewMarker for Stroke<V, State, Action> {}
impl<State, Action, V> View<State, Action, ViewCtx, DynMessage> for Stroke<V, State, Action>
impl<State, Action, V> View<State, Action, ViewCtx> for Stroke<V, State, Action>
where
State: 'static,
Action: 'static,
@ -298,7 +298,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.child.message(view_state, id_path, message, app_state)
}
}

View File

@ -25,7 +25,7 @@ fn create_element<R>(
})
}
impl<State: 'static, Action: 'static> OrphanView<Line, State, Action, DynMessage> for ViewCtx {
impl<State: 'static, Action: 'static> OrphanView<Line, State, Action> for ViewCtx {
type OrphanViewState = ();
type OrphanElement = Pod<web_sys::SvgLineElement>;
@ -77,12 +77,12 @@ impl<State: 'static, Action: 'static> OrphanView<Line, State, Action, DynMessage
_id_path: &[ViewId],
message: DynMessage,
_app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
MessageResult::Stale(message)
}
}
impl<State: 'static, Action: 'static> OrphanView<Rect, State, Action, DynMessage> for ViewCtx {
impl<State: 'static, Action: 'static> OrphanView<Rect, State, Action> for ViewCtx {
type OrphanViewState = ();
type OrphanElement = Pod<web_sys::SvgRectElement>;
@ -134,12 +134,12 @@ impl<State: 'static, Action: 'static> OrphanView<Rect, State, Action, DynMessage
_id_path: &[ViewId],
message: DynMessage,
_app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
MessageResult::Stale(message)
}
}
impl<State: 'static, Action: 'static> OrphanView<Circle, State, Action, DynMessage> for ViewCtx {
impl<State: 'static, Action: 'static> OrphanView<Circle, State, Action> for ViewCtx {
type OrphanViewState = ();
type OrphanElement = Pod<web_sys::SvgCircleElement>;
@ -189,12 +189,12 @@ impl<State: 'static, Action: 'static> OrphanView<Circle, State, Action, DynMessa
_id_path: &[ViewId],
message: DynMessage,
_app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
MessageResult::Stale(message)
}
}
impl<State: 'static, Action: 'static> OrphanView<BezPath, State, Action, DynMessage> for ViewCtx {
impl<State: 'static, Action: 'static> OrphanView<BezPath, State, Action> for ViewCtx {
type OrphanViewState = ();
type OrphanElement = Pod<web_sys::SvgPathElement>;
@ -246,7 +246,7 @@ impl<State: 'static, Action: 'static> OrphanView<BezPath, State, Action, DynMess
_id_path: &[ViewId],
message: DynMessage,
_app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
MessageResult::Stale(message)
}
}

View File

@ -13,7 +13,7 @@ use crate::{DomView, DynMessage, PodMut, ViewCtx};
pub struct Templated<V>(Rc<V>);
impl<V> ViewMarker for Templated<V> {}
impl<State, Action, V> View<State, Action, ViewCtx, DynMessage> for Templated<V>
impl<State, Action, V> View<State, Action, ViewCtx> for Templated<V>
where
State: 'static,
Action: 'static,
@ -21,7 +21,7 @@ where
{
type Element = V::Element;
type ViewState = <Rc<V> as View<State, Action, ViewCtx, DynMessage>>::ViewState;
type ViewState = <Rc<V> as View<State, Action, ViewCtx>>::ViewState;
fn build(&self, ctx: &mut ViewCtx, app_state: &mut State) -> (Self::Element, Self::ViewState) {
let type_id = TypeId::of::<Self>();
@ -80,7 +80,7 @@ where
id_path: &[ViewId],
message: DynMessage,
app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
self.0.message(view_state, id_path, message, app_state)
}
}

View File

@ -9,7 +9,7 @@ use crate::{DynMessage, Pod, PodFlags, ViewCtx};
// strings -> text nodes
macro_rules! impl_string_view {
($ty:ty) => {
impl<State, Action> OrphanView<$ty, State, Action, DynMessage> for ViewCtx {
impl<State, Action> OrphanView<$ty, State, Action> for ViewCtx {
type OrphanElement = Pod<web_sys::Text>;
type OrphanViewState = ();
@ -55,7 +55,7 @@ macro_rules! impl_string_view {
_id_path: &[ViewId],
message: DynMessage,
_app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
MessageResult::Stale(message)
}
}
@ -68,7 +68,7 @@ impl_string_view!(std::borrow::Cow<'static, str>);
macro_rules! impl_to_string_view {
($ty:ty) => {
impl<State, Action> OrphanView<$ty, State, Action, DynMessage> for ViewCtx {
impl<State, Action> OrphanView<$ty, State, Action> for ViewCtx {
type OrphanElement = Pod<web_sys::Text>;
type OrphanViewState = ();
@ -114,7 +114,7 @@ macro_rules! impl_to_string_view {
_id_path: &[ViewId],
message: DynMessage,
_app_state: &mut State,
) -> MessageResult<Action, DynMessage> {
) -> MessageResult<Action> {
MessageResult::Stale(message)
}
}