StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.
| 1 | use std::{ |
| 2 | any::{Any, TypeId}, |
| 3 | fmt::Debug, |
| 4 | }; |
| 5 | |
| 6 | /// Trait representing a Typed action. |
| 7 | /// |
| 8 | /// We require that an action implement a number of parent traits: |
| 9 | /// |
| 10 | /// - `Any` to support downcasting to the absolute type |
| 11 | /// - `Debug` so that we can show log messages about the action as it is dispatched |
| 12 | pub trait Action: Any + Debug + Send + Sync { |
| 13 | /// Convert this `Action` into a `dyn Any` reference, necessary for passing to the handler |
| 14 | /// function, as trait upcasting isn't yet stable, so we can't treat a value of `&dyn Action` |
| 15 | /// as a value of `&dyn Any` directly. |
| 16 | fn as_any(&self) -> &dyn Any; |
| 17 | |
| 18 | fn type_name(&self) -> &'static str { |
| 19 | std::any::type_name::<Self>() |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | /// Blanket impl for `Action`, allowing any type that implements the parent traits to |
| 24 | /// automatically be treated as an `Action`, without the app needing to do anything special |
| 25 | impl<T> Action for T |
| 26 | where |
| 27 | T: Any + Debug + Send + Sync, |
| 28 | { |
| 29 | fn as_any(&self) -> &dyn Any { |
| 30 | self |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | #[derive(PartialEq, Eq, Hash)] |
| 35 | pub(super) struct ActionType(TypeId); |
| 36 | |
| 37 | impl ActionType { |
| 38 | pub fn of<T: ?Sized + 'static>() -> Self { |
| 39 | ActionType(TypeId::of::<T>()) |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | impl From<&dyn Action> for ActionType { |
| 44 | fn from(action: &dyn Action) -> Self { |
| 45 | ActionType(action.type_id()) |
| 46 | } |
| 47 | } |
| 48 |