zino_channel/
cloud_event.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use serde::{Deserialize, Serialize};
use zino_core::{datetime::DateTime, JsonValue, Map, SharedString};

/// Cloud event.
/// See [the spec](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md).
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(default)]
pub struct CloudEvent<T = ()> {
    /// Spec version.
    #[serde(rename = "specversion")]
    spec_version: SharedString,
    /// Event ID.
    id: String,
    /// Event source.
    source: String,
    /// Event type.
    #[serde(rename = "type")]
    event_type: SharedString,
    /// Timestamp.
    #[serde(rename = "time")]
    timestamp: DateTime,
    /// Event data.
    #[serde(skip_serializing_if = "JsonValue::is_null")]
    data: JsonValue,
    /// Optional data content type.
    #[serde(rename = "datacontenttype")]
    data_content_type: Option<SharedString>,
    /// Optional data schema.
    #[serde(rename = "dataschema")]
    data_schema: Option<SharedString>,
    /// Optional subject.
    #[serde(skip_serializing_if = "Option::is_none")]
    subject: Option<SharedString>,
    /// Optional session ID.
    #[serde(rename = "sessionid")]
    #[serde(skip_serializing_if = "Option::is_none")]
    session_id: Option<String>,
    /// Extensions.
    #[serde(flatten)]
    extensions: T,
}

impl<T: Default> CloudEvent<T> {
    /// Creates a new instance.
    #[inline]
    pub fn new(
        id: impl ToString,
        source: impl ToString,
        event_type: impl Into<SharedString>,
    ) -> Self {
        Self {
            spec_version: "1.0".into(),
            id: id.to_string(),
            source: source.to_string(),
            event_type: event_type.into(),
            timestamp: DateTime::now(),
            data: JsonValue::Null,
            data_content_type: None,
            data_schema: None,
            subject: None,
            session_id: None,
            extensions: T::default(),
        }
    }
}

impl<T> CloudEvent<T> {
    /// Sets the event data.
    #[inline]
    pub fn set_data(&mut self, data: impl Into<JsonValue>) {
        self.data = data.into();
    }

    /// Sets the subject.
    #[inline]
    pub fn set_subject(&mut self, subject: impl Into<SharedString>) {
        self.subject = Some(subject.into());
    }

    /// Sets the session ID.
    #[inline]
    pub fn set_session_id(&mut self, session_id: impl ToString) {
        self.session_id = Some(session_id.to_string());
    }

    /// Returns the event ID as a `str`.
    #[inline]
    pub fn id(&self) -> &str {
        self.id.as_str()
    }

    /// Returns the event source as a `str`.
    #[inline]
    pub fn source(&self) -> &str {
        self.source.as_str()
    }

    /// Returns the event type as a `str`.
    #[inline]
    pub fn event_type(&self) -> &str {
        self.event_type.as_ref()
    }

    /// Returns a reference to the optional subject.
    #[inline]
    pub fn subject(&self) -> Option<&str> {
        self.subject.as_deref()
    }

    /// Returns a reference to the optional session ID.
    #[inline]
    pub fn session_id(&self) -> Option<&str> {
        self.session_id.as_deref()
    }

    /// Stringifies the event data as `String`.
    #[inline]
    pub fn stringify_data(&self) -> String {
        self.data.to_string()
    }
}

impl<T: Serialize> CloudEvent<T> {
    /// Consumes the event and returns as a json object.
    ///
    /// # Panics
    ///
    /// It will panic if the model cann't be converted to a json object.
    #[must_use]
    pub fn into_map(self) -> Map {
        match serde_json::to_value(self) {
            Ok(JsonValue::Object(map)) => map,
            _ => panic!("the cloud event cann't be converted to a json object"),
        }
    }
}