Crates.io | intrepid |
lib.rs | intrepid |
version | 0.1.6 |
source | src |
created_at | 2023-10-11 19:14:28.717545 |
updated_at | 2024-11-07 00:57:59.637867 |
description | Manage complex async business logic with ease |
homepage | |
repository | |
max_upload_size | |
id | 1000578 |
size | 34,954 |
Intrepid is a magic handler kit where most of the boilerplate work is already done. For cases where you'd like to get the ergonomics of Bevy or Actix-Web, but for your own stuff.
path_tree
. It's mostly just a matter of clean-up.Layer
impl that will work when that day comes?Handler might be "SimpleHandler", or in other words, it results in an ecosystem with a Frame, State dependency. The "canon handler" could be better designed as a wrapper trait that adds two specific trait dependencies.
ExtractFrame
trait, which describes a future that resolves to an implementing type. The extract frame approach lets us add asynchrony to this portion, and it lets us change (Frame, State)
into a form where state could be hypothetically extracted from a frame context, for example FrameContext<State>
.IntoFrame
trait, which describes a response type that is guaranteed to always resolve to something that fits the expectations of the surrounding ecosystem. Right now that guarantee isn't there.Together both of these traits could also improve documentation / error messaging.
Finally, if we have an async fn(impl ExtractFrame) -> impl IntoFrame
type of any sort, we know we can do the Stream / Sink guarantee in outer levels with no additional work, because we'll know if the State
of our FrameContext<State>
contains anything that implements our repo traits.
This might be the key to getting our composition boundaries in shape. Right now we need to know that something can turn into a Frame
in the innermost layer, and then as we progress to more concrete layers, we have to just say "ok give me a Frame
" in our generic notation or else shit gets cray.
The key to getting these layers into a more generic umbrella might be to create a secondary layer of traits, as outlined above with ExtractFrame
and IntoFrame
.
There's undoubtedly an opportunity to create a different function signature for handlers. Right now we have the ability to model out logic like this, and it's very powerful:
async fn(data, state) -> data
But, this might be more powerful:
async fn(data, state) -> (data, effects)
In other words, "things for the program to do", right now, can happen in the function, and "things to delegate to the program for whenever", that can go into effects.
This isn't a pressing need! Because right now, state
can represent the application machinery, and it's highly customizable in that regard. So, for example, application-modeled persistence and that kind of side-effect are already something we can register there.