use std::fmt;
use std::str::FromStr;
use relay_protocol::{Annotated, Empty, ErrorKind, FromValue, IntoValue, SkipSerialization, Value};
#[cfg(feature = "jsonschema")]
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(
Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Deserialize, Serialize, Default,
)]
#[cfg_attr(feature = "jsonschema", derive(JsonSchema))]
#[serde(rename_all = "lowercase")]
pub enum EventType {
Error,
Csp,
Hpkp,
ExpectCt,
ExpectStaple,
Nel,
Transaction,
UserReportV2,
#[serde(other)]
#[default]
Default,
}
#[derive(Clone, Copy, Debug)]
pub struct ParseEventTypeError;
impl fmt::Display for ParseEventTypeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "invalid event type")
}
}
impl std::error::Error for ParseEventTypeError {}
impl FromStr for EventType {
type Err = ParseEventTypeError;
fn from_str(string: &str) -> Result<Self, Self::Err> {
Ok(match string {
"default" => EventType::Default,
"error" => EventType::Error,
"csp" => EventType::Csp,
"hpkp" => EventType::Hpkp,
"expectct" => EventType::ExpectCt,
"expectstaple" => EventType::ExpectStaple,
"nel" => EventType::Nel,
"transaction" => EventType::Transaction,
"feedback" => EventType::UserReportV2,
_ => return Err(ParseEventTypeError),
})
}
}
impl fmt::Display for EventType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
EventType::Default => write!(f, "default"),
EventType::Error => write!(f, "error"),
EventType::Csp => write!(f, "csp"),
EventType::Hpkp => write!(f, "hpkp"),
EventType::ExpectCt => write!(f, "expectct"),
EventType::ExpectStaple => write!(f, "expectstaple"),
EventType::Nel => write!(f, "nel"),
EventType::Transaction => write!(f, "transaction"),
EventType::UserReportV2 => write!(f, "feedback"),
}
}
}
impl Empty for EventType {
#[inline]
fn is_empty(&self) -> bool {
false
}
}
impl FromValue for EventType {
fn from_value(value: Annotated<Value>) -> Annotated<Self> {
match String::from_value(value) {
Annotated(Some(value), mut meta) => match value.parse() {
Ok(eventtype) => Annotated(Some(eventtype), meta),
Err(_) => {
meta.add_error(ErrorKind::InvalidData);
meta.set_original_value(Some(value));
Annotated(None, meta)
}
},
Annotated(None, meta) => Annotated(None, meta),
}
}
}
impl IntoValue for EventType {
fn into_value(self) -> Value
where
Self: Sized,
{
Value::String(format!("{self}"))
}
fn serialize_payload<S>(&self, s: S, _behavior: SkipSerialization) -> Result<S::Ok, S::Error>
where
Self: Sized,
S: serde::Serializer,
{
Serialize::serialize(&self.to_string(), s)
}
}