use proc_macro2::TokenStream;
pub enum PayloadEncoding {
Json,
Cbor,
ProtoBuf,
}
impl TryFrom<&str> for PayloadEncoding {
type Error = &'static str;
fn try_from(s: &str) -> Result<Self, Self::Error> {
match s {
"json" => Ok(PayloadEncoding::Json),
"cbor" => Ok(PayloadEncoding::Cbor),
"proto" => Ok(PayloadEncoding::ProtoBuf),
_ => Err("Unexpected payload type for timesource event. Supported: \"json\", \"bincode\" or \"prost\"")
}
}
}
impl quote::ToTokens for PayloadEncoding {
fn to_tokens(&self, tokens: &mut TokenStream) {
let token = match self {
PayloadEncoding::Json => {
quote! {
fn encode_to_payload(&self) -> Result<timesource::EventPayloadEncoding, timesource::PersistedError> {
let value = serde_json::to_string(self).map_err(timesource::PersistedError::from)?;
Ok(timesource::EventPayloadEncoding::Json(value))
}
fn decode_from_payload(json: Option<&str>, bytes: Option<&[u8]>) -> Result<Self, timesource::PersistedError> {
match json {
Some(json) => serde_json::from_str(&json).map_err(timesource::PersistedError::from),
None => Err(timesource::PersistedError::JsonMissing)
}
}
}
}
PayloadEncoding::Cbor => {
quote! {
fn encode_to_payload(&self) -> Result<timesource::EventPayloadEncoding, timesource::PersistedError> {
let mut buf = vec![];
minicbor::encode(self, &mut buf).map_err(|err| timesource::PersistedError::MiniCborEncode(format!("{}", err)))?;
Ok(timesource::EventPayloadEncoding::Bytes(buf))
}
fn decode_from_payload(json: Option<&str>, bytes: Option<&[u8]>) -> Result<Self, timesource::PersistedError> {
match bytes {
Some(bytes) => minicbor::decode(bytes).map_err(timesource::PersistedError::from),
None => Err(timesource::PersistedError::BytesMissing)
}
}
}
}
PayloadEncoding::ProtoBuf => {
quote! {
fn encode_to_payload(&self) -> Result<timesource::EventPayloadEncoding, timesource::PersistedError> {
let bytes = prost::Message::encode_to_vec(self);
Ok(timesource::EventPayloadEncoding::Bytes(bytes))
}
fn decode_from_payload(json: Option<&str>, bytes: Option<&[u8]>) -> Result<Self, timesource::PersistedError> {
match bytes {
Some(bytes) => Self::decode(bytes).map_err(timesource::PersistedError::from),
None => Err(timesource::PersistedError::BytesMissing)
}
}
}
}
};
tokens.extend(quote! {
#token
});
}
}