Skip to main content

beetry_message/
lib.rs

1//! Message typing primitives for Beetry.
2//!
3//! This crate is an internal Beetry implementation crate and is not considered
4//! part of the public API. For public APIs, use the `beetry` crate.
5
6use std::cmp::Ordering;
7
8use getset::{CopyGetters, Getters};
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11/// Reexport macro needed to fully define Message to avoid users depending on
12/// external crate
13pub use type_hash;
14/// Describes the hash of the message type (and not concrete message type
15/// instance).
16#[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
70/// Trait for types that should be considered as a message type.
71pub 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}