use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MiddlewareKind {
Trace,
Cors,
Log,
RateLimit,
Auth,
}
impl MiddlewareKind {
pub fn as_str(self) -> &'static str {
match self {
MiddlewareKind::Trace => "trace",
MiddlewareKind::Cors => "cors",
MiddlewareKind::Log => "log",
MiddlewareKind::RateLimit => "rate_limit",
MiddlewareKind::Auth => "auth",
}
}
pub fn php_counterpart(self) -> &'static str {
match self {
MiddlewareKind::Trace => "\\think\\middleware\\SessionInit",
MiddlewareKind::Cors => "\\think\\middleware\\AllowCrossDomain",
MiddlewareKind::Log => "(none, sz-rust 自研,对齐 think-logger)",
MiddlewareKind::RateLimit => "(none, sz-rust 自研)",
MiddlewareKind::Auth => "app\\<app>\\middleware\\Auth",
}
}
}
impl fmt::Display for MiddlewareKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
pub const DEFAULT_ORDER: &[MiddlewareKind] = &[
MiddlewareKind::Trace,
MiddlewareKind::Cors,
MiddlewareKind::Log,
MiddlewareKind::RateLimit,
MiddlewareKind::Auth,
];
pub const PHP_GLOBAL_ORDER: &[MiddlewareKind] = &[MiddlewareKind::Trace, MiddlewareKind::Cors];
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_middleware_kind_as_str() {
assert_eq!(MiddlewareKind::Trace.as_str(), "trace");
assert_eq!(MiddlewareKind::Cors.as_str(), "cors");
assert_eq!(MiddlewareKind::Log.as_str(), "log");
assert_eq!(MiddlewareKind::RateLimit.as_str(), "rate_limit");
assert_eq!(MiddlewareKind::Auth.as_str(), "auth");
}
#[test]
fn test_middleware_kind_display() {
assert_eq!(MiddlewareKind::Trace.to_string(), "trace");
assert_eq!(MiddlewareKind::Cors.to_string(), "cors");
assert_eq!(MiddlewareKind::Log.to_string(), "log");
assert_eq!(MiddlewareKind::RateLimit.to_string(), "rate_limit");
assert_eq!(MiddlewareKind::Auth.to_string(), "auth");
}
#[test]
fn test_middleware_kind_php_counterpart() {
assert_eq!(
MiddlewareKind::Trace.php_counterpart(),
"\\think\\middleware\\SessionInit"
);
assert_eq!(
MiddlewareKind::Cors.php_counterpart(),
"\\think\\middleware\\AllowCrossDomain"
);
assert_eq!(
MiddlewareKind::Auth.php_counterpart(),
"app\\<app>\\middleware\\Auth"
);
}
#[test]
fn test_middleware_kind_eq_hash() {
use std::collections::HashSet;
let set: HashSet<MiddlewareKind> = [
MiddlewareKind::Trace,
MiddlewareKind::Cors,
MiddlewareKind::Trace,
]
.into_iter()
.collect();
assert_eq!(set.len(), 2);
assert!(set.contains(&MiddlewareKind::Trace));
assert!(set.contains(&MiddlewareKind::Cors));
assert!(!set.contains(&MiddlewareKind::Auth));
}
#[test]
fn test_middleware_kind_clone_copy() {
let kind = MiddlewareKind::Cors;
let cloned = kind; assert_eq!(kind, cloned);
}
#[test]
fn test_default_order_length() {
assert_eq!(DEFAULT_ORDER.len(), 5);
}
#[test]
fn test_default_order_trace_first() {
assert_eq!(DEFAULT_ORDER.first(), Some(&MiddlewareKind::Trace));
}
#[test]
fn test_default_order_auth_last() {
assert_eq!(DEFAULT_ORDER.last(), Some(&MiddlewareKind::Auth));
}
#[test]
fn test_default_order_cors_before_log() {
let cors_idx = DEFAULT_ORDER
.iter()
.position(|k| *k == MiddlewareKind::Cors)
.expect("Cors must be in DEFAULT_ORDER");
let log_idx = DEFAULT_ORDER
.iter()
.position(|k| *k == MiddlewareKind::Log)
.expect("Log must be in DEFAULT_ORDER");
assert!(cors_idx < log_idx, "Cors must execute before Log");
}
#[test]
fn test_default_order_rate_limit_before_auth() {
let rate_limit_idx = DEFAULT_ORDER
.iter()
.position(|k| *k == MiddlewareKind::RateLimit)
.expect("RateLimit must be in DEFAULT_ORDER");
let auth_idx = DEFAULT_ORDER
.iter()
.position(|k| *k == MiddlewareKind::Auth)
.expect("Auth must be in DEFAULT_ORDER");
assert!(
rate_limit_idx < auth_idx,
"RateLimit must execute before Auth"
);
}
#[test]
fn test_default_order_no_duplicates() {
use std::collections::HashSet;
let set: HashSet<MiddlewareKind> = DEFAULT_ORDER.iter().copied().collect();
assert_eq!(
set.len(),
DEFAULT_ORDER.len(),
"DEFAULT_ORDER has duplicates"
);
}
#[test]
fn test_default_order_contains_all_kinds() {
for kind in [
MiddlewareKind::Trace,
MiddlewareKind::Cors,
MiddlewareKind::Log,
MiddlewareKind::RateLimit,
MiddlewareKind::Auth,
] {
assert!(
DEFAULT_ORDER.contains(&kind),
"DEFAULT_ORDER missing {kind}"
);
}
}
#[test]
fn test_php_global_order_length() {
assert_eq!(PHP_GLOBAL_ORDER.len(), 2);
}
#[test]
fn test_php_global_order_matches_php_app_middleware() {
assert_eq!(PHP_GLOBAL_ORDER[0], MiddlewareKind::Trace); assert_eq!(PHP_GLOBAL_ORDER[1], MiddlewareKind::Cors); }
#[test]
fn test_php_global_order_is_prefix_of_default() {
assert!(DEFAULT_ORDER.starts_with(PHP_GLOBAL_ORDER));
}
}