use serde::{Deserialize, Serialize};
use std::fmt;
#[cfg(feature = "diesel")]
use std::io::Write;
#[cfg(feature = "diesel")]
use diesel::deserialize::{self, FromSql, FromSqlRow};
#[cfg(feature = "diesel")]
use diesel::prelude::*;
#[cfg(feature = "diesel")]
use diesel::serialize::{self, IsNull, Output, ToSql};
#[cfg(feature = "diesel")]
use diesel::{expression::AsExpression, sql_types::Text};
#[cfg(feature = "diesel")]
use diesel::mysql::{Mysql, MysqlValue};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(
feature = "diesel",
derive(diesel::expression::AsExpression, diesel::deserialize::FromSqlRow)
)]
#[cfg_attr(feature = "diesel", diesel(sql_type = Text))]
pub enum MisuseCode {
ProtocolDecryptionFailed,
ProtocolDeserializationFailed,
SchemaValidationFailed,
SchemaVersionInvalid,
SchemaVersionUnknown,
SemanticValidationFailed,
}
impl fmt::Display for MisuseCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let job = match self {
MisuseCode::ProtocolDecryptionFailed => "protocol_decryption_failed",
MisuseCode::ProtocolDeserializationFailed => "protocol_deserialization_failed",
MisuseCode::SchemaValidationFailed => "schema_validation_failed",
MisuseCode::SchemaVersionInvalid => "schema_version_invalid",
MisuseCode::SchemaVersionUnknown => "schema_version_unknown",
MisuseCode::SemanticValidationFailed => "semantic_validation_failed",
};
write!(f, "{}", job)
}
}
#[cfg(feature = "diesel")]
impl ToSql<Text, Mysql> for MisuseCode {
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> serialize::Result {
out.write_all(&*self.to_string().as_bytes())?;
Ok(IsNull::No)
}
}
#[cfg(feature = "diesel")]
impl FromSql<Text, Mysql> for MisuseCode {
fn from_sql(bytes: MysqlValue<'_>) -> deserialize::Result<Self> {
match bytes.as_bytes() {
b"protocol_decryption_failed" => Ok(MisuseCode::ProtocolDecryptionFailed),
b"protocol_deserialization_failed" => Ok(MisuseCode::ProtocolDeserializationFailed),
b"schema_version_invalid" => Ok(MisuseCode::SchemaVersionInvalid),
b"schema_validation_failed" => Ok(MisuseCode::SchemaValidationFailed),
b"schema_version_unknown" => Ok(MisuseCode::SchemaVersionUnknown),
b"semantic_validation_failed" => Ok(MisuseCode::SemanticValidationFailed),
_ => Err("Unrecognized misuse_code enum variant".into()),
}
}
}
#[derive(Debug, Deserialize, Serialize)]
pub struct ReportMisuseRequest {
pub receipt_id: String,
pub misuse: Vec<Misuse>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Misuse {
pub code: MisuseCode,
pub rule: Option<String>,
pub description: Option<String>,
}
impl Misuse {
pub fn from(code: MisuseCode) -> Self {
Misuse {
code,
rule: None,
description: None,
}
}
pub fn with_rule(self, rule: String) -> Self {
Misuse {
rule: Some(rule),
..self
}
}
pub fn with_description(self, description: String) -> Self {
Misuse {
description: Some(description),
..self
}
}
}