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}