telltale_language/ast/message.rs
1//! Message type definitions for choreographic protocols
2
3use proc_macro2::{Ident, TokenStream};
4
5/// Message type with optional payload
6///
7/// Represents a message that can be sent between roles in a choreography.
8/// Messages have a name and an optional payload type.
9///
10/// # Examples
11///
12/// ```ignore
13/// use quote::{format_ident, quote};
14/// use telltale_runtime::MessageType;
15///
16/// // Simple message without payload
17/// let ping = MessageType {
18/// name: format_ident!("Ping"),
19/// type_annotation: None,
20/// payload: None,
21/// };
22///
23/// // Message with payload
24/// let request = MessageType {
25/// name: format_ident!("Request"),
26/// type_annotation: Some(quote! { String }),
27/// payload: Some(quote! { data }),
28/// };
29/// ```
30#[derive(Debug, Clone)]
31pub struct MessageType {
32 /// The name identifier of the message
33 pub name: Ident,
34 /// Optional type annotation for the message (e.g., `<String>`, `<i32, bool>`)
35 pub type_annotation: Option<TokenStream>,
36 /// Optional payload type (as token stream)
37 pub payload: Option<TokenStream>,
38}
39
40impl PartialEq for MessageType {
41 fn eq(&self, other: &Self) -> bool {
42 self.name == other.name
43 && self
44 .type_annotation
45 .as_ref()
46 .map(std::string::ToString::to_string)
47 == other
48 .type_annotation
49 .as_ref()
50 .map(std::string::ToString::to_string)
51 && self.payload.as_ref().map(std::string::ToString::to_string)
52 == other.payload.as_ref().map(std::string::ToString::to_string)
53 }
54}
55
56impl Eq for MessageType {}
57
58impl std::hash::Hash for MessageType {
59 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
60 self.name.hash(state);
61 if let Some(ref type_annotation) = self.type_annotation {
62 type_annotation.to_string().hash(state);
63 }
64 if let Some(ref payload) = self.payload {
65 payload.to_string().hash(state);
66 }
67 }
68}
69
70impl MessageType {
71 /// Generate a Rust type identifier for this message
72 #[must_use]
73 pub fn to_ident(&self) -> Ident {
74 self.name.clone()
75 }
76}