1use crate::error;
2use base64::{self, Engine};
3use serde_derive::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Deserialize, Clone, Serialize)]
7pub struct EncodedMessage {
8 data: String,
9 #[serde(skip_serializing_if = "Option::is_none")]
10 attributes: Option<HashMap<String, String>>,
11}
12
13pub trait FromPubSubMessage
14where
15 Self: std::marker::Sized,
16{
17 fn from(message: EncodedMessage) -> Result<Self, error::Error>;
18}
19
20impl EncodedMessage {
21 pub fn decode(&self) -> Result<Vec<u8>, base64::DecodeError> {
22 base64::engine::general_purpose::STANDARD.decode(&self.data)
23 }
24
25 pub fn attributes(&self) -> Option<&HashMap<String, String>> {
26 self.attributes.as_ref()
27 }
28
29 pub fn new<T: serde::Serialize>(data: &T, attributes: Option<HashMap<String, String>>) -> Self {
30 let json = serde_json::to_string(data).unwrap();
31 Self::new_binary(&json, attributes)
32 }
33
34 pub fn new_binary<T: AsRef<[u8]> + std::marker::Sync>(
35 incoming: &T,
36 attributes: Option<HashMap<String, String>>,
37 ) -> Self {
38 let data = base64::engine::general_purpose::STANDARD.encode(&incoming);
39 EncodedMessage { data, attributes }
40 }
41}
42
43#[derive(Deserialize)]
44pub(crate) struct Message {
45 #[serde(alias = "ackId")]
46 pub(crate) ack_id: String,
47 pub(crate) message: EncodedMessage,
48}