use serde::Serialize;
use crate::error::ErrorVariant;
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct RouteInfo {
pub method: String,
pub path: String,
pub handler_name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub response_schema: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub request_schema: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub request_content_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub request_body_required: Option<bool>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub error_responses: Vec<ErrorVariant>,
}
impl RouteInfo {
#[allow(clippy::too_many_arguments)]
pub fn new(
method: impl Into<String>,
path: impl Into<String>,
handler_name: impl Into<String>,
response_schema: Option<serde_json::Value>,
request_schema: Option<serde_json::Value>,
request_content_type: Option<impl Into<String>>,
request_body_required: Option<bool>,
error_responses: Vec<ErrorVariant>,
) -> Self {
Self {
method: method.into(),
path: path.into(),
handler_name: handler_name.into(),
response_schema,
request_schema,
request_content_type: request_content_type.map(|s| s.into()),
request_body_required,
error_responses,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_route_info_new() {
let info = RouteInfo::new(
"GET",
"/users",
"list_users",
None,
None,
None::<String>,
None,
Vec::new(),
);
assert_eq!(info.method, "GET");
assert_eq!(info.path, "/users");
assert_eq!(info.handler_name, "list_users");
}
#[test]
fn test_route_info_with_params() {
let info = RouteInfo::new(
"GET",
"/users/:id",
"get_user",
None,
None,
None::<String>,
None,
Vec::new(),
);
assert_eq!(info.path, "/users/:id");
}
#[test]
fn test_route_info_clone() {
let info = RouteInfo::new(
"POST",
"/users",
"create_user",
None,
None,
None::<String>,
None,
Vec::new(),
);
let cloned = info.clone();
assert_eq!(info, cloned);
}
#[test]
fn test_route_info_serialize() {
let info = RouteInfo::new(
"GET",
"/health",
"health_check",
None,
None,
None::<String>,
None,
Vec::new(),
);
let json = serde_json::to_string(&info).unwrap();
assert!(json.contains("\"method\":\"GET\""));
assert!(json.contains("\"path\":\"/health\""));
assert!(json.contains("\"handler_name\":\"health_check\""));
}
#[test]
fn test_route_info_debug() {
let info = RouteInfo::new(
"DELETE",
"/users/:id",
"delete_user",
None,
None,
None::<String>,
None,
Vec::new(),
);
let debug = format!("{:?}", info);
assert!(debug.contains("DELETE"));
assert!(debug.contains("/users/:id"));
}
#[test]
fn test_route_info_with_error_responses() {
let errors = vec![ErrorVariant {
status: 404,
code: "NOT_FOUND",
description: "Resource not found",
}];
let info = RouteInfo::new(
"GET",
"/users/:id",
"get_user",
None,
None,
None::<String>,
None,
errors,
);
assert_eq!(info.error_responses.len(), 1);
assert_eq!(info.error_responses[0].status, 404);
}
}