1use std::cmp::Ordering;
7
8use getset::{CopyGetters, Getters};
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11pub use type_hash;
14#[derive(
17 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema,
18)]
19pub struct MessageHash {
20 hash: u64,
21}
22
23impl MessageHash {
24 #[must_use]
25 pub fn new(hash: u64) -> Self {
26 Self { hash }
27 }
28}
29
30#[derive(
31 Debug, Clone, PartialEq, Eq, Hash, CopyGetters, Getters, Serialize, Deserialize, JsonSchema,
32)]
33pub struct MessageSpec {
34 #[get = "pub"]
35 desc: String,
36 #[get_copy = "pub"]
37 hash: MessageHash,
38}
39
40impl MessageSpec {
41 #[must_use]
42 pub fn new<M>(desc: impl Into<String>) -> Self
43 where
44 M: Message,
45 {
46 Self {
47 desc: desc.into(),
48 hash: M::hash(),
49 }
50 }
51
52 #[must_use]
53 pub fn as_str(&self) -> &str {
54 &self.desc
55 }
56}
57
58impl PartialOrd for MessageSpec {
59 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
60 Some(self.cmp(other))
61 }
62}
63
64impl Ord for MessageSpec {
65 fn cmp(&self, other: &Self) -> Ordering {
66 self.desc.cmp(&other.desc)
67 }
68}
69
70pub trait Message: type_hash::TypeHash {
72 fn hash() -> MessageHash {
73 MessageHash::new(Self::type_hash())
74 }
75
76 fn as_str() -> &'static str {
77 std::any::type_name::<Self>()
78 .split("::")
79 .last()
80 .unwrap_or_else(|| std::any::type_name::<Self>())
81 }
82}