use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct Signal {
pub kind: SignalKind,
pub evidence: String,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub rfc_basis: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum SignalKind {
StatusCodeDiff,
HeaderPresence,
HeaderValue,
BodyDiff,
TimingDiff,
MetadataLeak,
InputReflection,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum ImpactClass {
Low,
Medium,
High,
}
impl std::fmt::Display for SignalKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::StatusCodeDiff => write!(f, "StatusCodeDiff"),
Self::HeaderPresence => write!(f, "HeaderPresence"),
Self::HeaderValue => write!(f, "HeaderValue"),
Self::BodyDiff => write!(f, "BodyDiff"),
Self::TimingDiff => write!(f, "TimingDiff"),
Self::MetadataLeak => write!(f, "MetadataLeak"),
Self::InputReflection => write!(f, "InputReflection"),
}
}
}
impl std::fmt::Display for ImpactClass {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Low => write!(f, "Low"),
Self::Medium => write!(f, "Medium"),
Self::High => write!(f, "High"),
}
}
}
#[cfg(test)]
mod tests {
use super::{ImpactClass, SignalKind};
#[test]
fn signal_kind_display() {
assert_eq!(format!("{}", SignalKind::StatusCodeDiff), "StatusCodeDiff");
assert_eq!(format!("{}", SignalKind::HeaderPresence), "HeaderPresence");
assert_eq!(format!("{}", SignalKind::HeaderValue), "HeaderValue");
assert_eq!(format!("{}", SignalKind::BodyDiff), "BodyDiff");
assert_eq!(format!("{}", SignalKind::TimingDiff), "TimingDiff");
assert_eq!(format!("{}", SignalKind::MetadataLeak), "MetadataLeak");
assert_eq!(
format!("{}", SignalKind::InputReflection),
"InputReflection"
);
}
#[test]
fn impact_class_display() {
assert_eq!(format!("{}", ImpactClass::Low), "Low");
assert_eq!(format!("{}", ImpactClass::Medium), "Medium");
assert_eq!(format!("{}", ImpactClass::High), "High");
}
}