Begin refactor to split unified stack into its own crate
parent: tbd commit: 95f5e65
Showing 5 changed files with 68 insertions and 1 deletion
Cargo.lock
@@ -814,6 +814,10 @@ dependencies = [ | ||
814 | 814 | ] |
815 | 815 | |
816 | 816 | [[package]] |
817 | name = "giterated-stack" | |
818 | version = "0.1.0" | |
819 | ||
820 | [[package]] | |
817 | 821 | name = "h2" |
818 | 822 | version = "0.3.21" |
819 | 823 | source = "registry+https://github.com/rust-lang/crates.io-index" |
Cargo.toml
@@ -1,5 +1,6 @@ | ||
1 | 1 | [workspace] |
2 | 2 | members = [ |
3 | 3 | "giterated-daemon", |
4 | "giterated-models" | |
4 | "giterated-models", | |
5 | "giterated-stack" | |
5 | 6 | ] |
5 | 6 | \ No newline at end of file |
giterated-stack/Cargo.toml
@@ -0,0 +1,8 @@ | ||
1 | [package] | |
2 | name = "giterated-stack" | |
3 | version = "0.1.0" | |
4 | edition = "2021" | |
5 | ||
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
7 | ||
8 | [dependencies] |
giterated-stack/README.md
@@ -0,0 +1,51 @@ | ||
1 | # Giterated Stack | |
2 | ||
3 | Giterated stack is the unified protocol stack implementation for Giterated. The architecture of the Giterated Stack allows for easy re-use of the same stack handling code across the entire Giterated ecosystem, from daemon to client. | |
4 | ||
5 | # Architecture | |
6 | ||
7 | Giterated's protocol operates using `Operation`'s on `Object`'s. The structure of a message is as follows: | |
8 | ``` | |
9 | object: String, | |
10 | operation_name: String, | |
11 | operation_payload: Vec<u8> | |
12 | ``` | |
13 | ||
14 | This same structure is represented in the Giterated Stack. Operations are implemented in terms of handlers, with a specific Object type and Operation type pair. For example: | |
15 | ||
16 | ``` | |
17 | async fn foo_handler(object: &User, operation: &FooOperation, state: FooState) -> Result<FooResult, OperationError<FooError>> { | |
18 | todo!() | |
19 | } | |
20 | ``` | |
21 | ||
22 | These handlers are then inserted into a handler structure that, at runtime, inspects the type signatures of the handlers and determines there are no issues. All operations flow through the handler structure and are transparently passed to handler functions. | |
23 | ||
24 | ## Operations and their Types | |
25 | ||
26 | Operations have their response and error types encoded in the type system using the `GiteratedOperation<O>` trait. Here is an example of how the operation used above would be defined. | |
27 | ||
28 | ``` | |
29 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | |
30 | pub struct FooOperation { | |
31 | pub bar: u64 | |
32 | } | |
33 | ||
34 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | |
35 | pub struct FooResult { | |
36 | pub baz: u64 | |
37 | } | |
38 | ||
39 | #[derive(Debug, Serialize, Deserialize, thiserror::Error)] | |
40 | #[error("foo error")] | |
41 | pub struct FooError; | |
42 | ||
43 | // GiteratedOperation additionally specifies which object type the operation | |
44 | // uses. In this example, we're implementing it for the User object. | |
45 | impl GiteratedOperation<User> for FooOperation { | |
46 | type Success = FooResult; | |
47 | type Failure = FooError; | |
48 | } | |
49 | ``` | |
50 | ||
51 | These trait implementations further guard operation handlers from being incorrect, as a function with mismatched parameters or return type is not a valid operation handler. | |
51 | \ No newline at end of file |