Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EventAdapter implementation (#1) #4

Open
wants to merge 118 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
6697475
Basic project structure with Event and VersionedEvent impls
ilslv Aug 13, 2021
a6e1847
Add Makefile, GitHub Actions, PR and Issue templates
ilslv Aug 13, 2021
238058d
Add EventInitialized, EventSourced and InitialEvent
ilslv Aug 13, 2021
83f9911
Fix CI
ilslv Aug 13, 2021
f31ca0c
Finally check uniqueness of event_type() and ver() at compile-time!
ilslv Aug 16, 2021
42c5b4d
Add docs explaining unique checks macro shenanigans [skip ci]
ilslv Aug 16, 2021
7dfe985
Add ability to skip uniqueness check for event_type and ver for Event…
ilslv Aug 17, 2021
7df18ef
Add more tests
ilslv Aug 17, 2021
d454eaf
Final touches
ilslv Aug 17, 2021
c61e8bb
Use nightly toolchain on CI
ilslv Aug 17, 2021
32aec5d
Fix CI
ilslv Aug 17, 2021
aa8f2b4
Remove stable and beta toolchains in testing
ilslv Aug 17, 2021
e815e60
CHANGELOG
ilslv Aug 17, 2021
11107d1
Merge branch 'master' into 1-event-sourcing
tyranron Aug 17, 2021
b048ca1
Introduce EventName and EventVersion and support them in proc-macros
ilslv Aug 17, 2021
c6f1ff9
CHANGELOG
ilslv Aug 17, 2021
d7647b6
Merge branch 'master' into 1-event-sourcing
ilslv Aug 17, 2021
c477378
Some corrections [skip ci]
tyranron Aug 17, 2021
5166708
Merge remote-tracking branch 'origin/1-event-sourcing' into 1-event-s…
tyranron Aug 17, 2021
4bd1c85
Replace event_type() with name() everywhere [skip ci]
ilslv Aug 17, 2021
8bc5e8c
Add es feature-gates [skip ci]
ilslv Aug 17, 2021
418b233
Split derive and es feature-gates [skip ci]
ilslv Aug 17, 2021
683456b
Use arcana-core crate for arcana-codegen-impl docs [skip ci]
ilslv Aug 17, 2021
7a8ceb5
WIP [skip ci]
ilslv Aug 17, 2021
8a9b4ec
Cover Event derive macro with docs [skip ci]
ilslv Aug 17, 2021
32f233f
Cover VersionedEvent derive macro with docs [skip ci]
ilslv Aug 17, 2021
18a0c1a
Move events uniqueness check to arcana_codegen crate [skip ci]
ilslv Aug 18, 2021
de5edea
Use only required number of events in uniqueness check [skip ci]
ilslv Aug 20, 2021
fb0260a
Add arcana-codegen-shim [skip ci]
ilslv Aug 20, 2021
d74ae8e
Add MSRV check
ilslv Aug 23, 2021
eff3a0a
Fix CI
ilslv Aug 23, 2021
373d0c1
Remove safety_guard dependency
ilslv Aug 23, 2021
4ad217b
Some corrections [skip ci]
tyranron Aug 24, 2021
088db1a
Corrections
ilslv Aug 25, 2021
8cea01b
Correction
ilslv Aug 25, 2021
0a40645
Disable -Z minimal-versions for now on CI MSRV check
ilslv Aug 25, 2021
8a84f85
Some corrections [skip ci]
tyranron Aug 25, 2021
23306f4
Merge remote-tracking branch 'origin/1-event-sourcing' into 1-event-s…
tyranron Aug 25, 2021
2d2c92d
Try to support generics in internal uniqueness glue code
ilslv Aug 26, 2021
843cae5
Hide docs dependencies behind the feature
ilslv Aug 26, 2021
7685c03
Corrections
ilslv Aug 26, 2021
549cde4
Implement core Adapter abstractions
ilslv Aug 30, 2021
a9e9fa1
WIP
ilslv Aug 31, 2021
5341cbf
Check uniqueness of event::Name and event::Version only on different …
ilslv Aug 31, 2021
2dde263
WIP [skip ci]
ilslv Aug 31, 2021
193fd2d
Extend support for event::Initial
ilslv Sep 2, 2021
a8580c8
Fix docs
ilslv Sep 2, 2021
10d9c5e
Merge branch 'master' into 1-EventAdapter
ilslv Sep 2, 2021
197a1cb
Add docs for Transformer derive macro
ilslv Sep 2, 2021
6b95a10
Cover Transformer derive macro with unit tests
ilslv Sep 2, 2021
a074323
Merge branch '1-unique-events-on-different-rust-types' into 1-EventAd…
ilslv Sep 2, 2021
c03777a
Add chat example
ilslv Sep 2, 2021
1ae2c55
Add chat example
ilslv Sep 2, 2021
7042731
Merge branch 'master' into 1-EventAdapter
ilslv Sep 2, 2021
3acdb08
Bootstrap [skip ci]
tyranron Sep 2, 2021
81f713a
WIP [skip ci]
ilslv Sep 2, 2021
8f49c41
WIP [skip ci]
ilslv Sep 2, 2021
49c1073
Add event::Sourcing and examples of usage
ilslv Sep 3, 2021
2cca463
Add docs
ilslv Sep 3, 2021
f36d0fa
Fix docs
ilslv Sep 3, 2021
9699690
Merge branch '1-event-sourcing' into 1-EventAdapter
ilslv Sep 3, 2021
a62e337
WIP
ilslv Sep 3, 2021
7521cb1
Add email example to demonstrate strategy::Split
ilslv Sep 3, 2021
a87105e
WIP [skip ci]
ilslv Sep 9, 2021
0282f9a
WIP [skip ci]
ilslv Sep 10, 2021
fc65304
WIP [skip ci]
ilslv Sep 13, 2021
6ac7b2c
Merge branch 'master' into 1-EventAdapter
ilslv Sep 13, 2021
8416aaa
WIP [skip ci]
ilslv Sep 13, 2021
12f8a34
WIP [skip ci]
ilslv Sep 15, 2021
32a5d97
Merge remote-tracking branch 'origin/1-EventAdapter' into 1-EventAdapter
ilslv Sep 15, 2021
d1e96b2
WIP [skip ci]
ilslv Sep 15, 2021
6090db0
WIP [skip ci]
ilslv Sep 20, 2021
076ccf8
Try generic Context instead of associated type [skip ci]
ilslv Sep 20, 2021
ad7a03a
Bootstrap Context with GATs [skip ci]
ilslv Sep 23, 2021
c35eb20
Generate Transformer impl with Event derive macro [skip ci]
ilslv Sep 23, 2021
08acc49
Bootstrap working version [skip ci]
ilslv Sep 23, 2021
fe266f2
Relax trait bounds [skip ci]
ilslv Sep 23, 2021
0dba918
Relax trait bounds [skip ci]
ilslv Sep 23, 2021
328cf1f
Clean up Event derive macro Transformer portion [skip ci]
ilslv Sep 23, 2021
7057ddd
Clean up Event derive macro Transformer portion [skip ci]
ilslv Sep 23, 2021
5db7732
WIP [skip ci]
ilslv Sep 27, 2021
fc2c541
Merge remote-tracking branch 'origin/1-EventAdapter' into 1-EventAdapter
ilslv Sep 27, 2021
c58555c
Fix Event derive macro spec [skip ci]
ilslv Sep 27, 2021
f4a9a4d
WIP [skip ci]
ilslv Sep 27, 2021
09c0207
Add event::Raw and usage examples [skip ci]
ilslv Sep 28, 2021
2cca7ac
Corrections
ilslv Sep 28, 2021
025d35b
Fix deps
ilslv Sep 28, 2021
2e06c30
Some bikesheddings
tyranron Sep 29, 2021
69c9129
Merge branch 'master' into 1-EventAdapter
ilslv Oct 12, 2021
c39af00
Make it work again
ilslv Oct 12, 2021
f04130e
Add test for deserialization error
ilslv Oct 12, 2021
fe6aa3d
Change lifetimes a bit [skip ci]
ilslv Oct 13, 2021
2c58629
Fix proc macro tests
ilslv Oct 13, 2021
879bae7
WIP [skip ci]
ilslv Oct 13, 2021
9cc95bc
Corrections
ilslv Oct 14, 2021
bda309f
Corrections
ilslv Oct 14, 2021
8e5486d
CHANGELOG
ilslv Oct 14, 2021
18d18ec
Some corrections [skip ci]
tyranron Oct 14, 2021
7512e06
Add event::Adapter derive macro [skip ci]
ilslv Oct 19, 2021
8c88604
Corrections [skip ci]
ilslv Oct 19, 2021
08f2909
Corrections [skip ci]
ilslv Oct 19, 2021
81b913d
Bootstrap working version [skip ci]
ilslv Nov 18, 2021
c0d4b70
Merge branch 'master' into 1-EventAdapter
ilslv Nov 18, 2021
93710a5
fix macros after 1.56 [skip ci]
ilslv Nov 18, 2021
df1bcd3
Corrections
ilslv Nov 19, 2021
23cec97
Corrections
ilslv Nov 19, 2021
42889eb
Dance around new GAT rules
ilslv Nov 19, 2021
40bd6d7
Make clippy happy
ilslv Nov 19, 2021
1654613
Docs
ilslv Nov 19, 2021
28b209a
Lint
ilslv Nov 19, 2021
da2c4ec
Corrections
ilslv Nov 22, 2021
eda0324
Revert "Corrections"
ilslv Dec 15, 2021
c065747
Revert "Lint"
ilslv Dec 15, 2021
0762876
Revert "Docs"
ilslv Dec 15, 2021
e544936
Revert "Make clippy happy"
ilslv Dec 15, 2021
c080b6c
Revert "Dance around new GAT rules"
ilslv Dec 15, 2021
5b69ff2
Corrections
ilslv Dec 15, 2021
93b89e6
Merge branch 'master' into 1-EventAdapter
ilslv Dec 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ jobs:
- arcana-codegen-shim
- arcana-codegen
- arcana
- arcana-example-chat
os:
- ubuntu
- macOS
Expand Down Expand Up @@ -168,6 +169,7 @@ jobs:
- arcana-codegen-shim
- arcana-codegen
- arcana
- arcana-example-chat
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Expand Down
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,18 @@ All user visible changes to this project will be documented in this file. This p
- Proc macros
- `Event` derive
- `VersionedEvent` derive

- Transforming Events
- Traits
- `Adapter`
- `Transformer`
- `Adapt`
- `Strategy`
- Structs
- `strategy::AsIs`
- `strategy::Custom`
- `strategy::Into`
- `strategy::Skip`
- `strategy::Split`



Expand Down
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ es = ["arcana-core/es"]
arcana-core = { version = "0.1.0-dev", path = "./core" }
arcana-codegen = { version = "0.1.0-dev", path = "./codegen", optional = true }

[[example]]
name = "event"
required-features = ["derive", "es"]

[workspace]
members = ["codegen", "codegen/impl", "codegen/shim", "core"]
members = [
"codegen", "codegen/impl", "codegen/shim",
"core",
"examples/chat",
]
3 changes: 2 additions & 1 deletion codegen/impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[features]
doc = ["arcana-core"] # only for generating documentation
doc = ["arcana-core", "futures"] # only for generating documentation

[dependencies]
proc-macro2 = { version = "1.0.4", default-features = false }
Expand All @@ -28,3 +28,4 @@ synthez = { version = "0.1.3", default-features = false }

# `doc` feature
arcana-core = { version = "0.1.0-dev", path = "../../core", features = ["es"], optional = true }
futures = { version = "0.3", default-features = false, optional = true }
185 changes: 185 additions & 0 deletions codegen/impl/src/es/event/adapter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
//! `#[derive(event::Adapter)]` macro implementation.

use std::convert::TryFrom;

use proc_macro2::TokenStream;
use quote::quote;
use syn::parse_quote;
use synthez::{ParseAttrs, Required, ToTokens};

/// Expands `#[derive(event::Adapter)]` macro.
///
/// # Errors
///
/// If failed to parse [`Attrs`].
pub fn derive(input: TokenStream) -> syn::Result<TokenStream> {
let input = syn::parse2::<syn::DeriveInput>(input)?;
let definition = Definition::try_from(input)?;

Ok(quote! { #definition })
}

/// Helper attributes of `#[derive(event::Adapter)]` macro.
#[derive(Debug, Default, ParseAttrs)]
pub struct Attrs {
/// [`Returning::Transformed`][0] associated type.
///
/// [0]: arcana_core::es::event::adapter::Returning::Transformed
#[parse(value, alias = into)]
pub transformed: Required<syn::Type>,

/// [`Returning::Error`][0] associated type.
///
/// [0]: arcana_core::es::event::adapter::Returning::Error
#[parse(value, alias = err)]
pub error: Option<syn::Type>,
}

/// Representation of a struct implementing [`event::Adapter`][0], used for
/// code generation.
///
/// [0]: arcana_core::es::event::Adapter
#[derive(Debug, ToTokens)]
#[to_tokens(append(impl_returning))]
pub struct Definition {
/// [`syn::Ident`](struct@syn::Ident) of this type.
pub ident: syn::Ident,

/// [`syn::Generics`] of this type.
pub generics: syn::Generics,

/// [`Returning::Transformed`][0] associated type.
///
/// [0]: arcana_core::es::event::adapter::Returning::Transformed
pub transformed: syn::Type,

/// [`Returning::Error`][0] associated type.
///
/// [0]: arcana_core::es::event::adapter::Returning::Error
pub error: syn::Type,
}

impl TryFrom<syn::DeriveInput> for Definition {
type Error = syn::Error;

fn try_from(input: syn::DeriveInput) -> syn::Result<Self> {
let attrs: Attrs = Attrs::parse_attrs("adapter", &input)?;

Ok(Self {
ident: input.ident,
generics: input.generics,
transformed: attrs.transformed.into_inner(),
error: attrs
.error
.unwrap_or_else(|| parse_quote! { ::std::convert::Infallible }),
})
}
}

impl Definition {
/// Generates code to derive [`Returning`][0] trait.
///
/// [0]: arcana_core::es::event::adapter::Returning
#[must_use]
pub fn impl_returning(&self) -> TokenStream {
let ty = &self.ident;
let (impl_gens, ty_gens, where_clause) = self.generics.split_for_impl();
let (transformed, error) = (&self.transformed, &self.error);

quote! {
#[automatically_derived]
impl #impl_gens ::arcana::es::event::adapter::Returning for
#ty #ty_gens
#where_clause
{
type Error = #error;
type Transformed = #transformed;
}
}
}
}

#[cfg(test)]
mod spec {
use quote::quote;
use syn::parse_quote;

#[test]
fn derives_impl() {
let input = parse_quote! {
#[adapter(into = Event, error = CustomError)]
struct Adapter;
};

let output = quote! {
#[automatically_derived]
impl ::arcana::es::event::adapter::Returning for Adapter {
type Error = CustomError;
type Transformed = Event;
}
};

assert_eq!(
super::derive(input).unwrap().to_string(),
output.to_string(),
);
}

#[test]
fn derives_impl_with_default_infallible_error() {
let input = parse_quote! {
#[adapter(into = Event)]
struct Adapter;
};

let output = quote! {
#[automatically_derived]
impl ::arcana::es::event::adapter::Returning for Adapter {
type Error = ::std::convert::Infallible;
type Transformed = Event;
}
};

assert_eq!(
super::derive(input).unwrap().to_string(),
output.to_string(),
);
}

#[test]
fn derives_impl_with_generics() {
let input = parse_quote! {
#[adapter(transformed = Event, err = CustomError)]
struct Adapter<T>(T);
};

let output = quote! {
#[automatically_derived]
impl<T> ::arcana::es::event::adapter::Returning for Adapter<T> {
type Error = CustomError;
type Transformed = Event;
}
};

assert_eq!(
super::derive(input).unwrap().to_string(),
output.to_string(),
);
}

#[test]
fn transformed_arg_is_required() {
let input = parse_quote! {
#[adapter(error = CustomError)]
struct Adapter;
};

let err = super::derive(input).unwrap_err();

assert_eq!(
err.to_string(),
"either `into` or `transformed` argument of `#[adapter]` attribute \
is expected to be present, but is absent",
);
}
}
Loading