forked from proxmox-mirrors/proxmox
testing a Router::api_dump method
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
536072c712
commit
a64832aac2
@ -46,6 +46,12 @@ fn main() {
|
|||||||
let www_dir = args.next().expect("expected a www/ subdirectory");
|
let www_dir = args.next().expect("expected a www/ subdirectory");
|
||||||
api::set_www_dir(www_dir.to_string());
|
api::set_www_dir(www_dir.to_string());
|
||||||
|
|
||||||
|
// show our api info:
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
serde_json::to_string_pretty(&api::ROUTER.api_dump()).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
// Construct our SocketAddr to listen on...
|
// Construct our SocketAddr to listen on...
|
||||||
let addr = ([0, 0, 0, 0], 3000).into();
|
let addr = ([0, 0, 0, 0], 3000).into();
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use std::sync::Once;
|
|||||||
|
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use http::Response;
|
use http::Response;
|
||||||
use serde_json::Value;
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
/// Method entries in a `Router` are actually just `&dyn ApiMethodInfo` trait objects.
|
/// Method entries in a `Router` are actually just `&dyn ApiMethodInfo` trait objects.
|
||||||
/// This contains all the info required to call, document, or command-line-complete parameters for
|
/// This contains all the info required to call, document, or command-line-complete parameters for
|
||||||
@ -31,6 +31,18 @@ pub struct Parameter {
|
|||||||
pub type_info: fn() -> &'static TypeInfo,
|
pub type_info: fn() -> &'static TypeInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Parameter {
|
||||||
|
pub fn api_dump(&self) -> (&'static str, Value) {
|
||||||
|
(
|
||||||
|
self.name,
|
||||||
|
json!({
|
||||||
|
"description": self.description,
|
||||||
|
"type": (self.type_info)().name,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Bare type info. Types themselves should also have a description, even if a method's parameter
|
/// Bare type info. Types themselves should also have a description, even if a method's parameter
|
||||||
/// usually overrides it. Ideally we can hyperlink the parameter to the type information in the
|
/// usually overrides it. Ideally we can hyperlink the parameter to the type information in the
|
||||||
/// generated documentation.
|
/// generated documentation.
|
||||||
@ -40,6 +52,12 @@ pub struct TypeInfo {
|
|||||||
pub complete_fn: Option<CompleteFn>,
|
pub complete_fn: Option<CompleteFn>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TypeInfo {
|
||||||
|
pub fn api_dump(&self) -> Value {
|
||||||
|
Value::String(self.name.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Until we can slap `#[api]` onto all the functions we can start translating our existing
|
/// Until we can slap `#[api]` onto all the functions we can start translating our existing
|
||||||
/// `ApiMethod` structs to this new layout.
|
/// `ApiMethod` structs to this new layout.
|
||||||
/// Otherwise this is mostly there so we can run the tests in the tests subdirectory without
|
/// Otherwise this is mostly there so we can run the tests in the tests subdirectory without
|
||||||
@ -80,6 +98,25 @@ impl<Body> ApiMethodInfo<Body> for ApiMethod<Body> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Body> dyn ApiMethodInfo<Body> + Send + Sync {
|
||||||
|
pub fn api_dump(&self) -> Value {
|
||||||
|
let parameters = Value::Object(std::iter::FromIterator::from_iter(
|
||||||
|
self.parameters()
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.api_dump())
|
||||||
|
.map(|(name, value)| (name.to_string(), value)),
|
||||||
|
));
|
||||||
|
|
||||||
|
json!({
|
||||||
|
"description": self.description(),
|
||||||
|
"protected": self.protected(),
|
||||||
|
"reload-timezone": self.reload_timezone(),
|
||||||
|
"parameters": parameters,
|
||||||
|
//"returns": self.return_type().api_dump()?, <- add api_dump() to TypeInfo
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// We're supposed to only use types in the API which implement `ApiType`, which forces types ot
|
/// We're supposed to only use types in the API which implement `ApiType`, which forces types ot
|
||||||
/// have a `verify` method. The idea is that all parameters used in the API are documented
|
/// have a `verify` method. The idea is that all parameters used in the API are documented
|
||||||
/// somewhere with their formats and limits, which are checked when entering and leaving API entry
|
/// somewhere with their formats and limits, which are checked when entering and leaving API entry
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use serde_json::Value;
|
use failure::Error;
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
use super::ApiMethodInfo;
|
use super::ApiMethodInfo;
|
||||||
|
|
||||||
@ -110,6 +111,58 @@ where
|
|||||||
Some((this, matched_params.map(Value::Object)))
|
Some((this, matched_params.map(Value::Object)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn api_dump(&self) -> Value {
|
||||||
|
let mut this = serde_json::Map::<String, Value>::new();
|
||||||
|
|
||||||
|
if let Some(get) = self.get {
|
||||||
|
this.insert("GET".to_string(), get.api_dump());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(put) = self.put {
|
||||||
|
this.insert("PUT".to_string(), put.api_dump());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(post) = self.post {
|
||||||
|
this.insert("POST".to_string(), post.api_dump());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(delete) = self.delete {
|
||||||
|
this.insert("DELETE".to_string(), delete.api_dump());
|
||||||
|
}
|
||||||
|
|
||||||
|
match &self.subroute {
|
||||||
|
None => (),
|
||||||
|
Some(SubRoute::Wildcard(name)) => {
|
||||||
|
this.insert("wildcard".to_string(), Value::String(name.to_string()));
|
||||||
|
}
|
||||||
|
Some(SubRoute::Directories(subdirs)) => {
|
||||||
|
for (dir, router) in subdirs.iter() {
|
||||||
|
this.insert(dir.to_string(), router.api_dump());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(SubRoute::Parameter(name, other)) => {
|
||||||
|
this.insert(
|
||||||
|
"sub-router".to_string(),
|
||||||
|
json!({
|
||||||
|
"parameter": name,
|
||||||
|
"router": other.api_dump(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Router as a builder methods:
|
||||||
|
//
|
||||||
|
|
||||||
|
impl<Body> Router<Body>
|
||||||
|
where
|
||||||
|
Self: Default,
|
||||||
|
{
|
||||||
/// Builder method to provide a `GET` method info.
|
/// Builder method to provide a `GET` method info.
|
||||||
pub fn get<I>(mut self, method: &'static I) -> Self
|
pub fn get<I>(mut self, method: &'static I) -> Self
|
||||||
where
|
where
|
||||||
|
Loading…
Reference in New Issue
Block a user