Skip to content

Commit

Permalink
first attempt at adding openapi generation from existing docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Yeastplume committed Dec 16, 2024
1 parent b93d88b commit 3bf6715
Show file tree
Hide file tree
Showing 7 changed files with 1,026 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ futures = "0.3.19"
serde_json = "1"
log = "0.4"
term = "0.6"
serde_yaml = "0.9"
syn = { version = "2.0", features = ["full", "parsing"] }

grin_api = { path = "./api", version = "5.4.0-alpha.0" }
grin_config = { path = "./config", version = "5.4.0-alpha.0" }
Expand Down
98 changes: 98 additions & 0 deletions api/src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2021 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Attribute macro for documenting API endpoints
///
/// Example usage:
/// ```rust
/// #[api_endpoint]
/// #[endpoint(
/// path = "/v1/status",
/// method = "GET",
/// summary = "Get node status",
/// description = "Returns the current status of the node"
/// )]
/// pub struct StatusHandler {
/// pub chain: Weak<Chain>,
/// }
/// ```
#[macro_export]
macro_rules! api_endpoint {
(
$(#[endpoint(
path = $path:expr,
method = $method:expr,
summary = $summary:expr,
description = $description:expr
$(, params = [$($param:expr),*])?
$(, response = $response:ty)?
)])*
pub struct $name:ident {
$($field:ident: $type:ty),* $(,)?
}
) => {
pub struct $name {
$($field: $type),*
}

impl ApiEndpoint for $name {
fn get_endpoint_spec() -> EndpointSpec {
EndpointSpec {
path: $path.to_string(),
method: $method.to_string(),
summary: $summary.to_string(),
description: $description.to_string(),
params: vec![$($($param.into()),*)?],
response: None $(Some(stringify!($response).to_string()))?
}
}
}
};
}

/// Trait for types that represent API endpoints
pub trait ApiEndpoint {
fn get_endpoint_spec() -> EndpointSpec;
}

/// Represents an OpenAPI endpoint specification
pub struct EndpointSpec {
pub path: String,
pub method: String,
pub summary: String,
pub description: String,
pub params: Vec<ParamSpec>,
pub response: Option<String>,
}

/// Represents an OpenAPI parameter specification
pub struct ParamSpec {
pub name: String,
pub description: String,
pub required: bool,
pub schema_type: String,
pub location: String,
}

impl From<(&str, &str, bool, &str, &str)> for ParamSpec {
fn from(tuple: (&str, &str, bool, &str, &str)) -> Self {
ParamSpec {
name: tuple.0.to_string(),
description: tuple.1.to_string(),
required: tuple.2,
schema_type: tuple.3.to_string(),
location: tuple.4.to_string(),
}
}
}
20 changes: 20 additions & 0 deletions src/bin/grin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern crate log;
use crate::config::config::SERVER_CONFIG_FILE_NAME;
use crate::core::global;
use crate::tools::check_seeds;
use crate::tools::openapi;
use crate::util::init_logger;
use clap::App;
use futures::channel::oneshot;
Expand Down Expand Up @@ -222,6 +223,25 @@ fn real_main() -> i32 {
0
}

// openapi command
("openapi", Some(args)) => {
let output = args.value_of("output").unwrap();
let format = args.value_of("format").unwrap();
match openapi::generate_openapi_spec(output, format) {
Ok(_) => {
println!(
"Successfully generated OpenAPI documentation at: {}",
output
);
0
}
Err(e) => {
error!("Failed to generate OpenAPI documentation: {}", e);
1
}
}
}

// If nothing is specified, try to just use the config file instead
// this could possibly become the way to configure most things
// with most command line options being phased out
Expand Down
15 changes: 15 additions & 0 deletions src/bin/grin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,18 @@ subcommands:
help: Output file to write the results to
long: output
takes_value: true
- openapi:
about: Generate OpenAPI documentation from JSON-RPC endpoints
args:
- output:
help: Output file path
short: o
long: output
takes_value: true
required: true
- format:
help: Output format (json or yaml)
short: f
long: format
takes_value: true
default_value: json
2 changes: 2 additions & 0 deletions src/bin/tools/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
mod seedcheck;

pub use seedcheck::check_seeds;

pub mod openapi;
Loading

0 comments on commit 3bf6715

Please sign in to comment.