-
Notifications
You must be signed in to change notification settings - Fork 1
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
Implement Events Handling (#1) #2
Conversation
FCM
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ilslv will discuss stuff additionally in videocall.
core/src/event/mod.rs
Outdated
/// | ||
/// _Note:_ This should effectively be a constant value, and should never | ||
/// change. | ||
fn event_type(&self) -> &'static str; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's change it to name
. Termin type
here was borrowed from other implementations, but tends to make more confusion. With name
we have a clear separation when we're saying "event name" and "event type".
core/src/lib.rs
Outdated
unused_results | ||
)] | ||
|
||
mod event; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's hide it behind es
(event sourcing) feature gate.
# Testing # | ||
########### | ||
|
||
test: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also let's add tests for MSRV (minimum supported Rust version) from the start.
core/src/event/mod.rs
Outdated
/// Wrapper-type intended for [`Event`]s that can initialize [`Sourced`] items. | ||
#[derive(Debug, RefCast)] | ||
#[repr(transparent)] | ||
pub struct Initial<Ev: ?Sized>(pub Ev); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clone
, Copy
and transparent Display
would be useful as well.
core/src/event/mod.rs
Outdated
#[repr(transparent)] | ||
pub struct Initial<Ev: ?Sized>(pub Ev); | ||
|
||
impl<Ev: Event + ?Sized, Agg: Initialized<Ev>> Sourced<Initial<Ev>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to use S
and "state" terminology here than "aggregate" as more general.
core/src/lib.rs
Outdated
#[doc(inline)] | ||
pub use event::{ | ||
Event, Initial as InitialEvent, Initialized as EventInitialized, | ||
Sourced as EventSourced, Versioned as VersionedEvent, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And let's call the module es
(event sourcing).
codegen/impl/src/event/versioned.rs
Outdated
|
||
use super::MAX_UNIQUE_EVENTS; | ||
|
||
/// Derives `arcana::VersionedEvent` for struct. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use links to arcana-core
crate. The crates layout allows it.
codegen/impl/src/event/versioned.rs
Outdated
ident: syn::Ident, | ||
generics: syn::Generics, | ||
event_type: syn::LitStr, | ||
event_ver: syn::LitInt, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These fields should have documantation.
codegen/impl/src/event/versioned.rs
Outdated
r#type: Option<syn::LitStr>, | ||
|
||
#[parse(value)] | ||
version: Option<syn::LitInt>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to see Attrs
defined before Definition
, following parse -> generate intuitive logic.
src/private.rs
Outdated
pub const fn all_unique<const N: usize>( | ||
types: [Option<(&str, u16)>; N], | ||
) -> bool { | ||
const fn str_eq(l: &str, r: &str) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's OK for this function to be outside.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ilslv still, discussion is required.
src/private.rs
Outdated
|
||
#[doc(hidden)] | ||
#[must_use] | ||
const fn str_eq(l: &str, r: &str) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No #[doc(hidden)]
. Describe it. And an appropriate // TODO:
for future removal.
core/src/es/mod.rs
Outdated
@@ -80,8 +79,8 @@ impl Version { | |||
} | |||
|
|||
impl<Ev: Versioned> Event for Ev { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?Sized
here.
src/private.rs
Outdated
#[doc(hidden)] | ||
#[macro_export] | ||
macro_rules! unique_event_type_and_ver_for_struct { | ||
($max_events:literal, $event_type:literal, $event_ver:literal) => { | ||
macro_rules! unique_event_name_and_ver_for_struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This macros better move to proc-macro machinery. There is no point to generate a half of an implementation via declarative and another part via proc macros. Better to keep things in a single place asap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed.
codegen/core/src/event/versioned.rs
Outdated
_ => { | ||
return Err(syn::Error::new_spanned( | ||
input, | ||
"`name` and `version` arguments expected", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have synthez::Required
for that.
codegen/core/src/event/versioned.rs
Outdated
|
||
impl #impl_generics #name #ty_generics #where_clause { | ||
#[automatically_derived] | ||
pub const fn __arcana_events() -> [(&'static str, u16); 1] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to hide such inner machinery from docs via #[doc(hidden)]
.
|
||
assert_eq!( | ||
format!("{}", err), | ||
"either `version` or `ver` argument of `#[event]` attribute is \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tyranron it looks like error message isn't deterministic. Sometimes I get either 'ver' or 'version' argument of '#[event]' attribute is expected to be present, but is absent
, so ver
and version
are switched (even on 2 CI runs (first, second) for the same code different jobs failed). As I understand this happens because synthez
uses HashSet<syn::Ident>
under the hood. HashSet
docs are saying that there is requirement
k1 == k2 -> hash(k1) == hash(k2)
And for syn::Ident
that promise isn't held up as I understand. PartialEq
impl compares ident itself and it's Span
, while Hash
impl simply hashes ident, ignoring it's Span
. This can be easily fixed specifically for error message generation, but I'm not sure if this thing can cause bigger ploblems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've accidentally started reviewing it without realizing it's still wip. Review and consider my changes.
codegen/core/Cargo.toml
Outdated
readme = "README.md" | ||
|
||
[dependencies] | ||
arcana-core = { version = "0.1.0-dev", path = "../../core", features = ["es"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't bloat dependencies with unused ones. If it's required for docs, let's introduce an appropriate feature, disabled by default.
codegen/core/src/es/event/mod.rs
Outdated
|
||
::arcana::codegen::sa::const_assert!( | ||
!::arcana::codegen::unique_events::has_duplicates( | ||
#name::__arcana_events() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That simply won't work with generics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FCM
Provide basic events sourcing (#2, #1)
- bootstrap project structure
Additionally:
- bootstrap CI pipeline
- bootstrap Makefile
/// #[derive(Event)] | ||
/// enum DuplicatedEvent { | ||
/// Any(AnyEvent), | ||
/// File(FileEvent), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ilslv it seems that exactly this situation should be legit.
I guess it should be allowed to use the same event type multiple times. This allows us easily to merge sets of events.
What should be forbidden really - is using the same event_name
+ event_ver
pair in different Rust types.
Let's merge this PR as it is, and resolve the described issue in a separate one.
Part of #1
Synopsis
Firstly we should implement abstractions for
Event
sSolution
Event
VersionedEvent
EventSourced
EventInitialised
InitialEvent
wrapperEvent
deriveVersionedEvent
deriveMakefile
Checklist
Draft:
prefixk::
labels appliedDraft:
prefix is removed