#![allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RestMethod {
Get,
Post,
Put,
Patch,
Delete,
}
#[derive(Debug, Clone)]
pub struct RestEndpoint {
pub path: String,
pub method: RestMethod,
pub summary: String,
pub request_schema: Option<String>,
pub response_schema: Option<String>,
pub tags: Vec<String>,
}
#[derive(Debug, Default)]
pub struct RestSchemaExport {
pub endpoints: Vec<RestEndpoint>,
pub base_url: String,
pub api_version: String,
}
pub fn new_rest_schema_export(base_url: &str, api_version: &str) -> RestSchemaExport {
RestSchemaExport {
endpoints: Vec::new(),
base_url: base_url.to_owned(),
api_version: api_version.to_owned(),
}
}
pub fn add_rest_endpoint(
export: &mut RestSchemaExport,
path: &str,
method: RestMethod,
summary: &str,
) {
export.endpoints.push(RestEndpoint {
path: path.to_owned(),
method,
summary: summary.to_owned(),
request_schema: None,
response_schema: None,
tags: Vec::new(),
});
}
pub fn set_request_schema(export: &mut RestSchemaExport, schema: &str) {
if let Some(ep) = export.endpoints.last_mut() {
ep.request_schema = Some(schema.to_owned());
}
}
pub fn set_response_schema(export: &mut RestSchemaExport, schema: &str) {
if let Some(ep) = export.endpoints.last_mut() {
ep.response_schema = Some(schema.to_owned());
}
}
pub fn add_endpoint_tag(export: &mut RestSchemaExport, tag: &str) {
if let Some(ep) = export.endpoints.last_mut() {
ep.tags.push(tag.to_owned());
}
}
pub fn rest_endpoint_count(export: &RestSchemaExport) -> usize {
export.endpoints.len()
}
pub fn endpoints_of_method(export: &RestSchemaExport, method: RestMethod) -> usize {
export
.endpoints
.iter()
.filter(|e| e.method == method)
.count()
}
pub fn find_rest_endpoint<'a>(
export: &'a RestSchemaExport,
path: &str,
method: RestMethod,
) -> Option<&'a RestEndpoint> {
export
.endpoints
.iter()
.find(|e| e.path == path && e.method == method)
}
pub fn method_name(m: RestMethod) -> &'static str {
match m {
RestMethod::Get => "GET",
RestMethod::Post => "POST",
RestMethod::Put => "PUT",
RestMethod::Patch => "PATCH",
RestMethod::Delete => "DELETE",
}
}
pub fn rest_schema_to_json(export: &RestSchemaExport) -> String {
format!(
r#"{{"base_url":"{}", "version":"{}", "endpoint_count":{}}}"#,
export.base_url,
export.api_version,
rest_endpoint_count(export)
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_export_empty() {
let e = new_rest_schema_export("https://api.example.com", "v1");
assert_eq!(rest_endpoint_count(&e), 0);
}
#[test]
fn add_endpoint_increments_count() {
let mut e = new_rest_schema_export("https://api.example.com", "v1");
add_rest_endpoint(&mut e, "/mesh", RestMethod::Get, "Get mesh");
assert_eq!(rest_endpoint_count(&e), 1);
}
#[test]
fn endpoints_of_method_get() {
let mut e = new_rest_schema_export("https://api.example.com", "v1");
add_rest_endpoint(&mut e, "/mesh", RestMethod::Get, "Get");
add_rest_endpoint(&mut e, "/mesh", RestMethod::Post, "Create");
assert_eq!(endpoints_of_method(&e, RestMethod::Get), 1);
}
#[test]
fn find_endpoint_success() {
let mut e = new_rest_schema_export("https://api.example.com", "v1");
add_rest_endpoint(&mut e, "/avatar", RestMethod::Post, "Create avatar");
assert!(find_rest_endpoint(&e, "/avatar", RestMethod::Post).is_some());
}
#[test]
fn find_endpoint_missing_returns_none() {
let e = new_rest_schema_export("https://api.example.com", "v1");
assert!(find_rest_endpoint(&e, "/nope", RestMethod::Get).is_none());
}
#[test]
fn method_name_get() {
assert_eq!(method_name(RestMethod::Get), "GET");
}
#[test]
fn method_name_delete() {
assert_eq!(method_name(RestMethod::Delete), "DELETE");
}
#[test]
fn request_schema_stored() {
let mut e = new_rest_schema_export("https://api.example.com", "v1");
add_rest_endpoint(&mut e, "/mesh", RestMethod::Post, "Create");
set_request_schema(&mut e, r#"{"type":"object"}"#);
assert!(e.endpoints[0].request_schema.is_some());
}
#[test]
fn json_contains_base_url() {
let e = new_rest_schema_export("https://mesh.api.com", "v2");
assert!(rest_schema_to_json(&e).contains("mesh.api.com"));
}
}