acton_reactive/traits/
acton_message.rs

1/*
2 * Copyright (c) 2024. Govcraft
3 *
4 * Licensed under either of
5 *   * Apache License, Version 2.0 (the "License");
6 *     you may not use this file except in compliance with the License.
7 *     You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8 *   * MIT license: http://opensource.org/licenses/MIT
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the applicable License for the specific language governing permissions and
14 * limitations under that License.
15 */
16use std::any::Any;
17use std::fmt::Debug;
18
19use dyn_clone::DynClone; // Required for cloning trait objects
20
21/// A marker trait for types that can be used as messages within the Acton framework.
22///
23/// This trait combines several standard library traits (`Any`, `Send`, `Sync`, `Debug`)
24/// with [`DynClone`] to ensure that messages are safe to send between threads,
25/// can be dynamically cloned (even as trait objects), support downcasting back to
26/// their concrete types, and are debuggable.
27///
28/// The `as_any` and `as_any_mut` methods are crucial for the framework's ability
29/// to handle messages generically and perform type-based dispatch (e.g., in message
30/// handlers registered via [`ManagedActor::act_on`](crate::actor::ManagedActor::act_on)).
31///
32/// A blanket implementation is provided, so any type `T` that satisfies the bounds
33/// (`T: Any + Send + Sync + Debug + DynClone + 'static`) automatically implements
34/// `ActonMessage`. Users typically only need to ensure their message structs/enums
35/// derive `Clone` and `Debug` and meet the `Send + Sync + 'static` requirements.
36pub trait ActonMessage: DynClone + Any + Send + Sync + Debug {
37    /// Returns a reference to the message as a dynamic [`Any`] trait object.
38    ///
39    /// This allows for runtime type introspection and downcasting using methods like
40    /// [`Any::downcast_ref`](std::any::Any::downcast_ref).
41    fn as_any(&self) -> &dyn Any;
42
43    /// Returns a mutable reference to the message as a dynamic [`Any`] trait object.
44    ///
45    /// This allows for mutable runtime type introspection and downcasting using methods like
46    /// [`Any::downcast_mut`](std::any::Any::downcast_mut).
47    fn as_any_mut(&mut self) -> &mut dyn Any;
48}
49
50// Implement DynClone for the trait object itself.
51dyn_clone::clone_trait_object!(ActonMessage);
52
53/// Blanket implementation of `ActonMessage` for qualifying types.
54///
55/// Any type `T` that is `Any + Send + Sync + Debug + DynClone + 'static` automatically
56/// implements `ActonMessage`. This simplifies defining custom message types.
57impl<T> ActonMessage for T
58where
59    T: Any + Send + Sync + Debug + DynClone + 'static, // DynClone replaces Clone here
60{
61    /// Implementation of `as_any` for the blanket impl.
62    #[inline]
63    fn as_any(&self) -> &dyn Any {
64        self
65    }
66
67    /// Implementation of `as_any_mut` for the blanket impl.
68    #[inline]
69    fn as_any_mut(&mut self) -> &mut dyn Any {
70        self
71    }
72}