Skip to content

Commit

Permalink
Ensure each combination of event::Name and event::Version correspond …
Browse files Browse the repository at this point in the history
…to single Rust type (#3, #1)

Additionally:
- support event::Initial in derive macros

Co-authored-by: tyranron <[email protected]>
  • Loading branch information
ilslv and tyranron authored Sep 2, 2021
1 parent 5a5e7ed commit 8efd428
Show file tree
Hide file tree
Showing 12 changed files with 387 additions and 197 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ readme = "README.md"

[features]
doc = ["arcana-codegen/doc"] # only for generating documentation
derive = ["arcana-codegen"]
derive = ["arcana-codegen", "arcana-core/codegen"]
es = ["arcana-core/es"]

[dependencies]
Expand Down
202 changes: 134 additions & 68 deletions codegen/impl/src/es/event/mod.rs

Large diffs are not rendered by default.

41 changes: 34 additions & 7 deletions codegen/impl/src/es/event/versioned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,14 @@ impl Definition {

let (event_name, event_ver) = (&self.event_name, &self.event_version);

// TODO: Replace `::std::concat!(...)` with `TypeId::of()` once it gets
// `const`ified.
// https://github.com/rust-lang/rust/issues/77125
quote! {
#[automatically_derived]
#[doc(hidden)]
impl #impl_gens ::arcana::codegen::UniqueEvents for #ty#ty_gens
#where_clause
impl #impl_gens ::arcana::es::event::codegen::Versioned for
#ty#ty_gens #where_clause
{
#[doc(hidden)]
const COUNT: usize = 1;
Expand All @@ -147,8 +150,20 @@ impl Definition {
impl #impl_gens #ty#ty_gens #where_clause {
#[doc(hidden)]
#[inline]
pub const fn __arcana_events() -> [(&'static str, u16); 1] {
[(#event_name, #event_ver)]
pub const fn __arcana_events() ->
[(&'static str, &'static str, u16); 1]
{
[(
::std::concat!(
::std::file!(),
"_",
::std::line!(),
"_",
::std::column!(),
),
#event_name,
#event_ver,
)]
}
}
}
Expand Down Expand Up @@ -182,7 +197,7 @@ mod spec {

#[automatically_derived]
#[doc(hidden)]
impl ::arcana::codegen::UniqueEvents for Event {
impl ::arcana::es::event::codegen::Versioned for Event {
#[doc(hidden)]
const COUNT: usize = 1;
}
Expand All @@ -192,8 +207,20 @@ mod spec {
impl Event {
#[doc(hidden)]
#[inline]
pub const fn __arcana_events() -> [(&'static str, u16); 1] {
[("event", 1)]
pub const fn __arcana_events() ->
[(&'static str, &'static str, u16); 1]
{
[(
::std::concat!(
::std::file!(),
"_",
::std::line!(),
"_",
::std::column!(),
),
"event",
1,
)]
}
}
};
Expand Down
45 changes: 22 additions & 23 deletions codegen/shim/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ use proc_macro::TokenStream;
/// For structs consider using [`#[derive(Versioned)]`](macro@VersionedEvent).
///
/// This macro ensures that every combination of [`Event::name`][0] and
/// [`Event::version`][1] are unique. The only limitation is that all the
/// underlying [`Event`] or [`Versioned`] impls should be derived too.
/// [`Event::version`][1] corresponds to a single Rust type. The only limitation
/// is that all the underlying [`Event`] or [`Versioned`] impls should be
/// derived too.
///
/// > __WARNING:__ Currently may not work with complex generics using where
/// > clause because of `const` evaluation limitations. Should be
Expand Down Expand Up @@ -60,20 +61,15 @@ use proc_macro::TokenStream;
/// struct ChatEvent;
///
/// #[derive(event::Versioned)]
/// #[event(name = "file", version = 1)]
/// struct FileEvent;
/// #[event(name = "chat", version = 1)]
/// struct DuplicateChatEvent;
///
/// // This fails to compile as contains different Rust types with the same
/// // `event::Name` and `event::Version`.
/// #[derive(Event)]
/// enum AnyEvent {
/// Chat(ChatEvent),
/// File(FileEvent),
/// }
///
/// // This fails to compile as contains `FileEvent` duplicated.
/// #[derive(Event)]
/// enum DuplicatedEvent {
/// Any(AnyEvent),
/// File(FileEvent),
/// DuplicateChat(DuplicateChatEvent),
/// }
/// ```
///
Expand All @@ -85,20 +81,23 @@ use proc_macro::TokenStream;
/// # struct ChatEvent;
/// #
/// # #[derive(event::Versioned)]
/// # #[event(name = "file", version = 1)]
/// # struct FileEvent;
/// #
/// # #[derive(Event)]
/// # enum AnyEvent {
/// # Chat(ChatEvent),
/// # File(FileEvent),
/// # }
/// # #[event(name = "chat", version = 1)]
/// # struct DuplicateChatEvent;
/// #
/// #[derive(Event)]
/// enum DuplicatedEvent {
/// Any(AnyEvent),
/// enum AnyEvent {
/// Chat(ChatEvent),
/// #[event(ignore)]
/// File(FileEvent),
/// DuplicateChat(DuplicateChatEvent),
/// }
///
/// // This example doesn't need `#[event(ignore)]` attribute, as each
/// // combination of `event::Name` and `event::Version` corresponds to a single
/// // Rust type.
/// #[derive(Event)]
/// enum MoreEvents {
/// Chat(ChatEvent),
/// ChatOnceAgain(ChatEvent),
/// }
/// ```
///
Expand Down
1 change: 0 additions & 1 deletion codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,5 @@
)]

pub mod es;
pub mod unique_events;

pub use static_assertions as sa;
74 changes: 0 additions & 74 deletions codegen/src/unique_events.rs

This file was deleted.

2 changes: 2 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ repository = "https://github.com/arcana-rs/arcana"
readme = "README.md"

[features]
codegen = ["sealed"] # only enables codegen glue
es = []

[dependencies]
derive_more = { version = "0.99", features = ["deref", "deref_mut", "display", "into"], default-features = false }
ref-cast = "1.0"
sealed = { version = "0.3", optional = true }

[package.metadata.docs.rs]
all-features = true
Expand Down
Loading

0 comments on commit 8efd428

Please sign in to comment.