summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Müller <m.mueller@ifm.com>2022-05-31 11:24:51 +0200
committerMarcel Müller <m.mueller@ifm.com>2022-05-31 11:24:51 +0200
commit3dc51be974294fafa60c9b73280b9be241277765 (patch)
tree5aa990ac60e6117d18659132991f6341c8fe1ecb
parent031832c6f22156694f0822265c5dd7b3b9683b9d (diff)
parent519ec731579a226aac53cec65c6b20cacfd3f586 (diff)
Merge branch 'feature/add_type_uuids_to_messages' into feature/add_tedge_api_only
-rw-r--r--Cargo.lock27
-rw-r--r--crates/core/tedge_api/Cargo.toml1
-rw-r--r--crates/core/tedge_api/README.md5
-rw-r--r--crates/core/tedge_api/examples/heartbeat.rs11
-rw-r--r--crates/core/tedge_api/examples/print_config.rs1
-rw-r--r--crates/core/tedge_api/examples/universal_log.rs11
-rw-r--r--crates/core/tedge_api/src/address.rs24
-rw-r--r--crates/core/tedge_api/src/lib.rs7
-rw-r--r--crates/core/tedge_api/src/message.rs64
-rw-r--r--crates/core/tedge_api/src/plugin.rs80
-rw-r--r--crates/core/tedge_api/tedge_config_derive/src/lib.rs2
11 files changed, 151 insertions, 82 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 100ef892..36dac215 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2872,6 +2872,7 @@ dependencies = [
"tokio-util 0.7.0",
"toml",
"tracing",
+ "type-uuid",
]
[[package]]
@@ -3396,6 +3397,26 @@ dependencies = [
]
[[package]]
+name = "type-uuid"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15043bca41f43205c9b0055d365a405d81b8e4a8ff99c36b263cf79ad1f4c051"
+dependencies = [
+ "type-uuid-derive",
+]
+
+[[package]]
+name = "type-uuid-derive"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e090ee857961c746ecf7fb596022493ffaad54d189061df49f7a0cf17796dc1"
+dependencies = [
+ "quote 1.0.18",
+ "syn 1.0.93",
+ "uuid",
+]
+
+[[package]]
name = "typed-arena"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3490,6 +3511,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
+
+[[package]]
name = "value-bag"
version = "1.0.0-alpha.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/crates/core/tedge_api/Cargo.toml b/crates/core/tedge_api/Cargo.toml
index 5546ed2b..a4ff92ab 100644
--- a/crates/core/tedge_api/Cargo.toml
+++ b/crates/core/tedge_api/Cargo.toml
@@ -21,6 +21,7 @@ termimad = "0.20.1"
nu-ansi-term = "0.45.1"
tedge_config_derive = { version = "0.1.0", path = "tedge_config_derive" }
tracing = "0.1"
+type-uuid = "0.1.2"
[dev-dependencies]
pretty_assertions = "1.2.1"
diff --git a/crates/core/tedge_api/README.md b/crates/core/tedge_api/README.md
index 340faa23..8c59231a 100644
--- a/crates/core/tedge_api/README.md
+++ b/crates/core/tedge_api/README.md
@@ -85,7 +85,10 @@ others.
For example:
```rust
-#[derive(Debug)]
+use tedge_api::{Message, TypeUuid};
+
+#[derive(Debug, TypeUuid)]
+#[uuid = "b60dd50c-ccef-4204-b370-18bbbb68d6e2"]
struct Value(f64);
impl Message for Value {}
diff --git a/crates/core/tedge_api/examples/heartbeat.rs b/crates/core/tedge_api/examples/heartbeat.rs
index 654c4311..8d64232a 100644
--- a/crates/core/tedge_api/examples/heartbeat.rs
+++ b/crates/core/tedge_api/examples/heartbeat.rs
@@ -4,23 +4,26 @@ use async_trait::async_trait;
use futures::FutureExt;
use tedge_api::{
address::ReplySenderFor,
- message::MessageType,
- plugin::{AcceptsReplies, BuiltPlugin, Handle, Message, PluginDeclaration, PluginExt},
+ message::{AcceptsReplies, Message, MessageType},
+ plugin::{BuiltPlugin, Handle, PluginDeclaration, PluginExt},
Address, CancellationToken, Plugin, PluginBuilder, PluginConfiguration, PluginDirectory,
PluginError,
};
use tokio::sync::RwLock;
+use type_uuid::TypeUuid;
+#[derive(Debug, TypeUuid)]
+#[uuid = "94916be9-17ba-4bca-a3a0-408d33136fed"]
/// A message that represents a heartbeat that gets sent to plugins
-#[derive(Debug)]
struct Heartbeat;
impl Message for Heartbeat {}
impl AcceptsReplies for Heartbeat {
type Reply = HeartbeatStatus;
}
+#[derive(Debug, TypeUuid)]
+#[uuid = "a6d03c65-51bf-4f89-b383-c67c9ed8533b"]
/// The reply for a heartbeat
-#[derive(Debug)]
enum HeartbeatStatus {
Alive,
Degraded,
diff --git a/crates/core/tedge_api/examples/print_config.rs b/crates/core/tedge_api/examples/print_config.rs
index ba6e7a6b..8be855e0 100644
--- a/crates/core/tedge_api/examples/print_config.rs
+++ b/crates/core/tedge_api/examples/print_config.rs
@@ -1,3 +1,4 @@
+#![allow(dead_code, unused)]
use std::collections::HashMap;
use nu_ansi_term::Color;
diff --git a/crates/core/tedge_api/examples/universal_log.rs b/crates/core/tedge_api/examples/universal_log.rs
index 82ff3130..064ffa22 100644
--- a/crates/core/tedge_api/examples/universal_log.rs
+++ b/crates/core/tedge_api/examples/universal_log.rs
@@ -4,19 +4,22 @@ use async_trait::async_trait;
use futures::FutureExt;
use tedge_api::{
address::ReplySenderFor,
- message::{AnyMessage, MessageType},
- plugin::{AnyMessages, BuiltPlugin, Handle, Message, PluginDeclaration, PluginExt},
+ message::{AnyMessage, Message, MessageType},
+ plugin::{AnyMessages, BuiltPlugin, Handle, PluginDeclaration, PluginExt},
Address, CancellationToken, Plugin, PluginBuilder, PluginConfiguration, PluginDirectory,
PluginError,
};
use tokio::sync::RwLock;
+use type_uuid::TypeUuid;
/// A message that represents a heartbeat that gets sent to plugins
-#[derive(Debug)]
+#[derive(Debug, TypeUuid)]
+#[uuid = "1f807f7b-888f-4881-a1b5-16380e32f8c2"]
struct Heartbeat;
impl Message for Heartbeat {}
-#[derive(Debug)]
+#[derive(Debug, TypeUuid)]
+#[uuid = "346e233f-c24a-47e0-a15b-3ec0d1e19019"]
struct RandomData;
impl Message for RandomData {}
diff --git a/crates/core/tedge_api/src/address.rs b/crates/core/tedge_api/src/address.rs
index 4f786ea5..4249ecfc 100644
--- a/crates/core/tedge_api/src/address.rs
+++ b/crates/core/tedge_api/src/address.rs
@@ -4,10 +4,7 @@ use futures::future::BoxFuture;
use tokio::sync::RwLock;
use tracing::{instrument, trace};
-use crate::{
- message::MessageType,
- plugin::{AcceptsReplies, Message},
-};
+use crate::message::{AcceptsReplies, Message, MessageType};
#[doc(hidden)]
pub type AnyMessageBox = Box<dyn Message>;
@@ -363,13 +360,16 @@ pub trait Contains<M: Message> {}
///
/// ```rust
/// # use tedge_api::{Message, make_receiver_bundle};
+/// # use type_uuid::TypeUuid;
///
-/// #[derive(Debug)]
+/// #[derive(Debug, TypeUuid)]
+/// #[uuid = "b4e62630-0404-4d39-b435-95d777029887"]
/// struct IntMessage(u8);
///
/// impl Message for IntMessage { }
///
-/// #[derive(Debug)]
+/// #[derive(Debug, TypeUuid)]
+/// #[uuid = "92734ceb-7b65-499a-95cd-17164f1b3729"]
/// struct StatusMessage(String);
///
/// impl Message for StatusMessage { }
@@ -406,15 +406,17 @@ mod tests {
use static_assertions::{assert_impl_all, assert_not_impl_any};
use tokio::sync::RwLock;
+ use type_uuid::TypeUuid;
use crate::{
address::{InnerMessageSender, ReplyReceiverFor, ReplySenderFor},
make_receiver_bundle,
- plugin::{AcceptsReplies, Message},
+ message::{AcceptsReplies, Message},
Address,
};
- #[derive(Debug)]
+ #[derive(Debug, TypeUuid)]
+ #[uuid = "df2b8bb3-8c15-49bb-8d11-cc14d7f3b000"]
struct Foo;
impl Message for Foo {}
@@ -422,12 +424,14 @@ mod tests {
type Reply = Bar;
}
- #[derive(Debug)]
+ #[derive(Debug, TypeUuid)]
+ #[uuid = "953a243d-333a-4870-8297-272fff6262b5"]
struct Bar;
impl Message for Bar {}
- #[derive(Debug)]
+ #[derive(Debug, TypeUuid)]
+ #[uuid = "fe98650c-b067-47f4-8fd8-2f3ed04fdc21"]
struct Blub;
impl Message for Blub {}
diff --git a/crates/core/tedge_api/src/lib.rs b/crates/core/tedge_api/src/lib.rs
index 5a9f77bb..f9716981 100644
--- a/crates/core/tedge_api/src/lib.rs
+++ b/crates/core/tedge_api/src/lib.rs
@@ -8,7 +8,7 @@
/// All the parts required to write a plugin
pub mod plugin;
-pub use plugin::{Message, Plugin, PluginBuilder, PluginConfiguration, PluginDirectory, PluginExt};
+pub use plugin::{Plugin, PluginBuilder, PluginConfiguration, PluginDirectory, PluginExt};
/// Generic representation of a configuration
pub mod config;
@@ -24,7 +24,7 @@ pub use error::PluginError;
/// Predefined messages
pub mod message;
-pub use message::CoreMessages;
+pub use message::{Message, CoreMessages};
/// Cancellation token used by `tedge_api`
///
@@ -33,6 +33,9 @@ pub use tokio_util::sync::CancellationToken;
/// Derive macro for self-describing configurations
pub use tedge_config_derive::Config;
+/// Derive macro for type uuids
+pub use type_uuid::TypeUuid;
+
#[doc(hidden)]
pub mod _internal {
pub use futures::future::BoxFuture;
diff --git a/crates/core/tedge_api/src/message.rs b/crates/core/tedge_api/src/message.rs
index 3e4a6249..1e63a368 100644
--- a/crates/core/tedge_api/src/message.rs
+++ b/crates/core/tedge_api/src/message.rs
@@ -1,6 +1,35 @@
+use downcast_rs::{impl_downcast, DowncastSync};
use serde::Serialize;
+use type_uuid::{TypeUuid, TypeUuidDynamic};
-use crate::{address::AnyMessageBox, plugin::Message};
+use crate::address::AnyMessageBox;
+
+/// An object that can be sent between [`Plugin`]s
+///
+/// This trait is a marker trait for all types that can be used as messages which can be sent
+/// between plugins in thin-edge.
+pub trait Message:
+ Send + std::fmt::Debug + DynMessage + DowncastSync + TypeUuidDynamic + 'static
+{
+}
+
+impl_downcast!(sync Message);
+
+/// A bag of messages making it easier to work with dynamic messages
+pub trait DynMessage {
+ /// Get the type name of this message
+ fn type_name(&self) -> &'static str {
+ std::any::type_name::<Self>()
+ }
+}
+
+impl<M: 'static> DynMessage for M {}
+
+/// Register that the [`Message`] can receive replies of kind `R`: [`Message`]
+pub trait AcceptsReplies: Message {
+ /// The reply type that can be sent to implementing messages as replies
+ type Reply: Message;
+}
/// A message that can contain any other message
///
@@ -8,7 +37,8 @@ use crate::{address::AnyMessageBox, plugin::Message};
/// otherwise.
///
/// To construct it, you will need to have a message and call [`AnyMessage::from_message`]
-#[derive(Debug)]
+#[derive(Debug, TypeUuid)]
+#[uuid = "e7e5c87b-2022-4687-8650-DEADBEEEEEEF"]
pub struct AnyMessage(pub(crate) AnyMessageBox);
impl std::ops::Deref for AnyMessage {
@@ -50,11 +80,14 @@ pub struct MessageType {
kind: MessageKind,
}
+#[derive(Clone, PartialEq, Debug)]
+struct Uuid([u8; 16]);
+
#[derive(Debug, Clone, Serialize)]
enum MessageKind {
Wildcard,
#[serde(skip)]
- Typed(std::any::TypeId),
+ Typed(Uuid),
}
impl MessageType {
@@ -79,26 +112,26 @@ impl MessageType {
/// Get the [`MessageType`] for a `M`:[`Message`]
#[must_use]
- pub fn for_message<M: Message>() -> Self {
- let id = std::any::TypeId::of::<M>();
+ pub fn for_message<M: Message + TypeUuid>() -> Self {
+ let id = M::UUID;
MessageType {
name: std::any::type_name::<M>(),
- kind: if id == std::any::TypeId::of::<AnyMessage>() {
+ kind: if id == AnyMessage::UUID {
MessageKind::Wildcard
} else {
- MessageKind::Typed(id)
+ MessageKind::Typed(Uuid(id))
},
}
}
pub(crate) fn from_message(msg: &dyn Message) -> Self {
- let id = msg.type_id();
+ let id = msg.uuid();
MessageType {
name: msg.type_name(),
- kind: if id == std::any::TypeId::of::<AnyMessage>() {
+ kind: if id == AnyMessage::UUID {
MessageKind::Wildcard
} else {
- MessageKind::Typed(id)
+ MessageKind::Typed(Uuid(id))
},
}
}
@@ -111,7 +144,8 @@ impl MessageType {
}
/// A message to tell the core to stop thin-edge
-#[derive(Debug)]
+#[derive(Debug, TypeUuid)]
+#[uuid = "812b7235-671f-4722-b01a-333578b2a4ea"]
pub struct StopCore;
impl Message for StopCore {}
@@ -120,16 +154,20 @@ crate::make_receiver_bundle!(pub struct CoreMessages(StopCore));
#[cfg(test)]
mod tests {
+ use type_uuid::TypeUuid;
+
use crate::Message;
use super::{AnyMessage, MessageType};
- #[derive(Debug)]
+ #[derive(Debug, TypeUuid)]
+ #[uuid = "0c2ed228-5ff0-4ba5-a0d3-3648f7eb6558"]
struct Bar;
impl Message for Bar {}
- #[derive(Debug)]
+ #[derive(Debug, TypeUuid)]
+ #[uuid = "8c3beacb-327d-422d-a914-47006d521ba5"]
struct Foo;
impl Message for Foo {}
diff --git a/crates/core/tedge_api/src/plugin.rs b/crates/core/tedge_api/src/plugin.rs
index 431127cf..718dbf67 100644
--- a/crates/core/tedge_api/src/plugin.rs
+++ b/crates/core/tedge_api/src/plugin.rs
@@ -6,6 +6,7 @@
use futures::future::BoxFuture;
use std::any::Any;
+use type_uuid::TypeUuid;
use downcast_rs::{impl_downcast, DowncastSync};
@@ -15,7 +16,7 @@ use crate::{
address::{InternalMessage, ReceiverBundle, ReplySenderFor},
config::ConfigDescription,
error::{DirectoryError, PluginError},
- message::{CoreMessages, MessageType},
+ message::{CoreMessages, Message, MessageType},
Address,
};
@@ -96,10 +97,12 @@ pub trait PluginBuilder<PD: PluginDirectory>: Sync + Send + 'static {
///
/// ```no_run
/// # use tedge_api::{Plugin, plugin::BuiltPlugin, PluginError, PluginExt, PluginDirectory, PluginBuilder, PluginConfiguration};
+ /// # use type_uuid::TypeUuid;
///
- /// #[derive(Debug)]
+ /// #[derive(Debug, TypeUuid)]
+ /// #[uuid = "46f5d318-4158-4726-83dd-9b310cae3328"]
/// struct MyMessage;
- /// impl tedge_api::plugin::Message for MyMessage { }
+ /// impl tedge_api::Message for MyMessage { }
///
/// struct MyPluginBuilder;
/// struct MyPlugin; // + some impl Plugin for MyPlugin
@@ -217,10 +220,12 @@ pub trait PluginBuilder<PD: PluginDirectory>: Sync + Send + 'static {
/// # use tedge_api::PluginBuilder;
/// # use tedge_api::PluginDirectory;
/// # use tedge_api::PluginExt;
+ /// # use type_uuid::TypeUuid;
///
- /// #[derive(Debug)]
+ /// #[derive(Debug, TypeUuid)]
+ /// #[uuid = "39046e3e-05ad-4b16-bbf1-8c2d2da5b668"]
/// struct MyMessage;
- /// impl tedge_api::plugin::Message for MyMessage { }
+ /// impl tedge_api::Message for MyMessage { }
///
///
/// struct MyPluginBuilder;
@@ -383,11 +388,13 @@ impl HandleTypes {
/// # use tedge_api::address::ReplySenderFor;
/// # use tedge_api::PluginError;
/// # use tedge_api::PluginExt;
+ /// # use type_uuid::TypeUuid;
///
- /// #[derive(Debug)]
+ /// #[derive(Debug, TypeUuid)]
+ /// #[uuid = "1276aa9c-5e04-4ab3-a987-61d89765ab33"]
/// struct Heartbeat;
///
- /// impl tedge_api::plugin::Message for Heartbeat { }
+ /// impl tedge_api::Message for Heartbeat { }
///
/// struct HeartbeatPlugin;
///
@@ -414,19 +421,19 @@ impl HandleTypes {
/// # type HandledMessages = (Heartbeat,);
/// # }
///
- /// println!("{:#?}", HeartbeatPlugin::get_handled_types());
+ /// println!("{:#x?}", HeartbeatPlugin::get_handled_types());
/// // This will print something akin to:
/// //
- /// // HandleTypes(
- /// // [
- /// // (
- /// // "rust_out::main::_doctest_main_src_plugin_rs_102_0::Heartbeat",
- /// // TypeId {
- /// // t: 15512189350087767644,
- /// // },
- /// // ),
- /// // ],
- /// // )
+ /// // HandleTypes(
+ /// // [
+ /// // MessageType {
+ /// // name: "rust_out::main::_doctest_main_src_plugin_rs_373_0::Heartbeat",
+ /// // kind: Typed(
+ /// // Uuid([ 0x12, 0x76, 0xaa, 0x9c, 0x5e, 0x4, 0x4a, 0xb3, 0xa9, 0x87, 0x61, 0xd8, 0x97, 0x65, 0xab, 0x33, ])
+ /// // ),
+ /// // },
+ /// // ],
+ /// // )
/// ```
pub fn declare_handlers_for<P: PluginDeclaration>() -> HandleTypes
where
@@ -436,30 +443,6 @@ impl HandleTypes {
}
}
-/// An object that can be sent between [`Plugin`]s
-///
-/// This trait is a marker trait for all types that can be used as messages which can be sent
-/// between plugins in thin-edge.
-pub trait Message: Send + std::fmt::Debug + DynMessage + DowncastSync + 'static {}
-
-impl_downcast!(sync Message);
-
-/// A bag of messages making it easier to work with dynamic messages
-pub trait DynMessage {
- /// Get the type name of this message
- fn type_name(&self) -> &'static str {
- std::any::type_name::<Self>()
- }
-}
-
-impl<M: 'static> DynMessage for M {}
-
-/// Register that the [`Message`] can receive replies of kind `R`: [`Message`]
-pub trait AcceptsReplies: Message {
- /// The reply type that can be sent to implementing messages as replies
- type Reply: Message;
-}
-
/// A bundle of messages
///
/// This trait is implemented on types that represent a bundle of different types of messages.
@@ -552,7 +535,7 @@ pub trait DoesHandle<M: MessageBundle> {
macro_rules! impl_does_handle_tuple {
() => {};
($cur:ident $($rest:tt)*) => {
- impl<$cur: Message, $($rest: Message,)* PLUG: Plugin + Handle<$cur> $(+ Handle<$rest>)*> DoesHandle<($cur, $($rest),*)> for PLUG {
+ impl<$cur: Message + TypeUuid, $($rest: Message + TypeUuid,)* PLUG: Plugin + Handle<$cur> $(+ Handle<$rest>)*> DoesHandle<($cur, $($rest),*)> for PLUG {
fn into_built_plugin(self) -> BuiltPlugin {
fn handle_message<'a, $cur: Message, $($rest: Message,)* PLUG: Plugin + Handle<$cur> $(+ Handle<$rest>)*>(
plugin: &'a dyn Any,
@@ -602,6 +585,8 @@ macro_rules! impl_does_handle_tuple {
};
}
+impl_does_handle_tuple!(M10 M9 M8 M7 M6 M5 M4 M3 M2 M1);
+
impl MessageBundle for () {
fn get_ids() -> Vec<MessageType> {
vec![]
@@ -673,7 +658,7 @@ macro_rules! impl_msg_bundle_tuple {
($cur, impl_msg_bundle_tuple!(@rec_tuple $($rest)*))
};
($cur:ident $($rest:tt)*) => {
- impl<$cur: Message, $($rest: Message),*> MessageBundle for ($cur,$($rest),*) {
+ impl<$cur: Message + TypeUuid, $($rest: Message + TypeUuid),*> MessageBundle for ($cur,$($rest),*) {
fn get_ids() -> Vec<MessageType> {
vec![
MessageType::for_message::<$cur>(),
@@ -687,20 +672,21 @@ macro_rules! impl_msg_bundle_tuple {
}
impl_msg_bundle_tuple!(M10 M9 M8 M7 M6 M5 M4 M3 M2 M1);
-impl_does_handle_tuple!(M10 M9 M8 M7 M6 M5 M4 M3 M2 M1);
#[cfg(test)]
mod tests {
- use crate::{plugin::DynMessage, Message};
+ use crate::{message::DynMessage, Message};
use super::{Plugin, PluginBuilder};
use static_assertions::assert_obj_safe;
+ use type_uuid::TypeUuid;
// Object Safety
assert_obj_safe!(PluginBuilder<()>);
assert_obj_safe!(Plugin);
- #[derive(Debug)]
+ #[derive(Debug, TypeUuid)]
+ #[uuid = "44d61fba-0055-4333-86bf-e96e06f7aea8"]
struct Blub;
impl Message for Blub {}
diff --git a/crates/core/tedge_api/tedge_config_derive/src/lib.rs b/crates/core/tedge_api/tedge_config_derive/src/lib.rs
index 5c34dbf2..b2a97098 100644
--- a/crates/core/tedge_api/tedge_config_derive/src/lib.rs
+++ b/crates/core/tedge_api/tedge_config_derive/src/lib.rs
@@ -1,6 +1,6 @@
use proc_macro::TokenStream as TS;
use proc_macro2::TokenStream;
-use proc_macro_error::{abort, emit_error, proc_macro_error, OptionExt, ResultExt};
+use proc_macro_error::{abort, proc_macro_error, OptionExt, ResultExt};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{
parse_macro_input, Attribute, DeriveInput, Ident, Lit, LitStr, Meta, MetaNameValue, NestedMeta,