add openapi parsing
This commit is contained in:
parent
cf70a331d7
commit
b9ba6e60d1
54
Cargo.lock
generated
54
Cargo.lock
generated
|
@ -136,9 +136,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.9"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80f656be11ddf91bd709454d15d5bd896fbaf4cc3314e69349e4d1569f5b46cd"
|
||||
checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799"
|
||||
dependencies = [
|
||||
"indenter",
|
||||
"once_cell",
|
||||
|
@ -191,9 +191,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
|
||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
@ -237,6 +237,16 @@ dependencies = [
|
|||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generator"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"eyre",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.0"
|
||||
|
@ -341,9 +351,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
|
||||
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
|
@ -531,9 +541,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.0"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
|
@ -561,18 +571,18 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
version = "1.0.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -684,18 +694,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.192"
|
||||
version = "1.0.195"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
|
||||
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.192"
|
||||
version = "1.0.195"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
|
||||
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -704,9 +714,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.108"
|
||||
version = "1.0.111"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
||||
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -762,9 +772,9 @@ checksum = "b5097ec7ea7218135541ad96348f1441d0c616537dd4ed9c47205920c35d7d97"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.39"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -983,9 +993,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.4.1"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
|
||||
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
workspace = { members = ["generator"] }
|
||||
[package]
|
||||
name = "forgejo-api"
|
||||
version = "0.1.0"
|
||||
|
|
12
generator/Cargo.toml
Normal file
12
generator/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "generator"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
eyre = "0.6.11"
|
||||
serde = { version = "1.0.195", features = ["derive"] }
|
||||
serde_json = "1.0.111"
|
||||
url = { version = "2.5.0", features = ["serde"] }
|
17
generator/src/main.rs
Normal file
17
generator/src/main.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
use std::ffi::OsString;
|
||||
|
||||
mod openapi;
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
let spec = get_spec()?;
|
||||
dbg!(spec);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_spec() -> eyre::Result<openapi::OpenApiV2> {
|
||||
let path = std::env::var_os("FORGEJO_API_SPEC_PATH")
|
||||
.unwrap_or_else(|| OsString::from("./api_spec.json"));
|
||||
let file = std::fs::read(path)?;
|
||||
let spec = serde_json::from_slice::<openapi::OpenApiV2>(&file)?;
|
||||
Ok(spec)
|
||||
}
|
338
generator/src/openapi.rs
Normal file
338
generator/src/openapi.rs
Normal file
|
@ -0,0 +1,338 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use url::Url;
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct OpenApiV2 {
|
||||
pub swagger: String,
|
||||
pub info: SpecInfo,
|
||||
pub host: Option<Url>,
|
||||
pub base_path: Option<String>,
|
||||
pub schemes: Option<Vec<String>>,
|
||||
pub consumes: Option<Vec<String>>,
|
||||
pub produces: Option<Vec<String>>,
|
||||
pub paths: BTreeMap<String, PathItem>,
|
||||
pub definitions: Option<BTreeMap<String, Schema>>,
|
||||
pub parameters: Option<BTreeMap<String, Parameter>>,
|
||||
pub responses: Option<BTreeMap<String, Response>>,
|
||||
pub security_definitions: Option<BTreeMap<String, SecurityScheme>>,
|
||||
pub security: Option<Vec<BTreeMap<String, Vec<String>>>>,
|
||||
pub tags: Option<Vec<Tag>>,
|
||||
pub external_docs: Option<ExternalDocs>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct SpecInfo {
|
||||
pub title: String,
|
||||
pub description: Option<String>,
|
||||
pub terms_of_service: Option<String>,
|
||||
pub contact: Option<Contact>,
|
||||
pub license: Option<License>,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Contact {
|
||||
pub name: Option<String>,
|
||||
pub url: Option<String>,
|
||||
pub email: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct License {
|
||||
pub name: String,
|
||||
pub url: Option<Url>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct PathItem {
|
||||
#[serde(rename = "$ref")]
|
||||
pub _ref: Option<String>,
|
||||
pub get: Option<Operation>,
|
||||
pub put: Option<Operation>,
|
||||
pub post: Option<Operation>,
|
||||
pub delete: Option<Operation>,
|
||||
pub options: Option<Operation>,
|
||||
pub head: Option<Operation>,
|
||||
pub patch: Option<Operation>,
|
||||
pub parameters: Option<Vec<MaybeRef<Parameter>>>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Operation {
|
||||
pub tags: Option<Vec<String>>,
|
||||
pub summary: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub external_docs: Option<ExternalDocs>,
|
||||
pub operation_id: Option<String>,
|
||||
pub consumes: Option<Vec<String>>,
|
||||
pub produces: Option<Vec<String>>,
|
||||
pub parameters: Option<Vec<MaybeRef<Parameter>>>,
|
||||
pub responses: Responses,
|
||||
pub schemes: Option<Vec<String>>,
|
||||
pub deprecated: Option<bool>,
|
||||
pub security: Option<Vec<BTreeMap<String, Vec<String>>>>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct ExternalDocs {
|
||||
pub description: Option<String>,
|
||||
pub url: Url,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Parameter {
|
||||
pub name: String,
|
||||
#[serde(rename = "in")]
|
||||
pub _in: String,
|
||||
pub description: Option<String>,
|
||||
pub required: Option<bool>,
|
||||
pub schema: Option<MaybeRef<Schema>>,
|
||||
#[serde(rename = "type")]
|
||||
pub _type: Option<ParameterType>,
|
||||
pub format: Option<String>,
|
||||
pub allow_empty_value: Option<bool>,
|
||||
pub items: Option<Items>,
|
||||
pub collection_format: Option<CollectionFormat>,
|
||||
pub default: Option<serde_json::Value>,
|
||||
pub maximum: Option<f64>,
|
||||
pub exclusive_maximum: Option<bool>,
|
||||
pub minimum: Option<f64>,
|
||||
pub exclusive_minimum: Option<bool>,
|
||||
pub max_length: Option<u64>,
|
||||
pub min_length: Option<u64>,
|
||||
pub pattern: Option<String>, // should be regex
|
||||
pub max_items: Option<u64>,
|
||||
pub min_items: Option<u64>,
|
||||
pub unique_items: Option<bool>,
|
||||
#[serde(rename = "enum")]
|
||||
pub _enum: Option<Vec<serde_json::Value>>,
|
||||
pub multiple_of: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub enum ParameterType {
|
||||
String,
|
||||
Number,
|
||||
Integer,
|
||||
Boolean,
|
||||
Array,
|
||||
File,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub enum CollectionFormat {
|
||||
Csv,
|
||||
Ssv,
|
||||
Tsv,
|
||||
Pipes,
|
||||
Multi,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Items {
|
||||
#[serde(rename = "type")]
|
||||
pub _type: ParameterType,
|
||||
pub format: Option<String>,
|
||||
pub items: Option<Box<Items>>,
|
||||
pub collection_format: Option<CollectionFormat>,
|
||||
pub default: Option<serde_json::Value>,
|
||||
pub maximum: Option<f64>,
|
||||
pub exclusive_maximum: Option<bool>,
|
||||
pub minimum: Option<f64>,
|
||||
pub exclusive_minimum: Option<bool>,
|
||||
pub max_length: Option<u64>,
|
||||
pub min_length: Option<u64>,
|
||||
pub pattern: Option<String>, // should be regex
|
||||
pub max_items: Option<u64>,
|
||||
pub min_items: Option<u64>,
|
||||
pub unique_items: Option<bool>,
|
||||
#[serde(rename = "enum")]
|
||||
pub _enum: Option<Vec<serde_json::Value>>,
|
||||
pub multiple_of: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Responses {
|
||||
pub default: Option<MaybeRef<Response>>,
|
||||
#[serde(flatten)]
|
||||
pub http_codes: BTreeMap<String, MaybeRef<Response>>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Response {
|
||||
pub description: String,
|
||||
pub schema: Option<Schema>,
|
||||
pub headers: Option<BTreeMap<String, Header>>,
|
||||
pub examples: Option<BTreeMap<String, serde_json::Value>>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Header {
|
||||
pub description: Option<String>,
|
||||
#[serde(rename = "type")]
|
||||
pub _type: ParameterType,
|
||||
pub format: Option<String>,
|
||||
pub items: Option<Items>,
|
||||
pub collection_format: Option<CollectionFormat>,
|
||||
pub default: Option<serde_json::Value>,
|
||||
pub maximum: Option<f64>,
|
||||
pub exclusive_maximum: Option<bool>,
|
||||
pub minimum: Option<f64>,
|
||||
pub exclusive_minimum: Option<bool>,
|
||||
pub max_length: Option<u64>,
|
||||
pub min_length: Option<u64>,
|
||||
pub pattern: Option<String>, // should be regex
|
||||
pub max_items: Option<u64>,
|
||||
pub min_items: Option<u64>,
|
||||
pub unique_items: Option<bool>,
|
||||
#[serde(rename = "enum")]
|
||||
pub _enum: Option<Vec<serde_json::Value>>,
|
||||
pub multiple_of: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Tag {
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
pub external_docs: Option<ExternalDocs>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Schema {
|
||||
pub format: Option<String>,
|
||||
pub title: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub default: Option<serde_json::Value>,
|
||||
pub multiple_of: Option<u64>,
|
||||
pub maximum: Option<f64>,
|
||||
pub exclusive_maximum: Option<bool>,
|
||||
pub minimum: Option<f64>,
|
||||
pub exclusive_minimum: Option<bool>,
|
||||
pub max_length: Option<u64>,
|
||||
pub min_length: Option<u64>,
|
||||
pub pattern: Option<String>, // should be regex
|
||||
pub max_items: Option<u64>,
|
||||
pub min_items: Option<u64>,
|
||||
pub unique_items: Option<bool>,
|
||||
pub max_properties: Option<u64>,
|
||||
pub min_properties: Option<u64>,
|
||||
pub required: Option<Vec<String>>,
|
||||
#[serde(rename = "enum")]
|
||||
pub _enum: Option<Vec<serde_json::Value>>,
|
||||
#[serde(rename = "type")]
|
||||
pub _type: Option<SchemaType>,
|
||||
|
||||
pub discriminator: Option<String>,
|
||||
pub read_only: Option<bool>,
|
||||
pub xml: Option<Xml>,
|
||||
pub external_docs: Option<ExternalDocs>,
|
||||
pub example: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(untagged)]
|
||||
pub enum SchemaType {
|
||||
One(Primitive),
|
||||
List(Vec<Primitive>),
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub enum Primitive {
|
||||
Array,
|
||||
Boolean,
|
||||
Integer,
|
||||
Number,
|
||||
Null,
|
||||
Object,
|
||||
String,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct Xml {
|
||||
pub name: Option<String>,
|
||||
pub namespace: Option<Url>,
|
||||
pub prefix: Option<String>,
|
||||
pub attribute: Option<bool>,
|
||||
pub wrapped: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub struct SecurityScheme {
|
||||
#[serde(flatten)]
|
||||
pub _type: SecurityType,
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"), tag = "type")]
|
||||
pub enum SecurityType {
|
||||
Basic,
|
||||
ApiKey {
|
||||
name: String,
|
||||
#[serde(rename = "in")]
|
||||
_in: KeyIn,
|
||||
},
|
||||
OAuth2 {
|
||||
#[serde(flatten)]
|
||||
flow: OAuth2Flow,
|
||||
scopes: BTreeMap<String, String>,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"))]
|
||||
pub enum KeyIn {
|
||||
Query,
|
||||
Header,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(rename_all(deserialize = "camelCase"), tag = "flow")]
|
||||
pub enum OAuth2Flow {
|
||||
Implicit {
|
||||
authorization_url: Url,
|
||||
},
|
||||
Password{
|
||||
token_url: Url,
|
||||
},
|
||||
Application{
|
||||
token_url: Url,
|
||||
},
|
||||
AccessCode{
|
||||
authorization_url: Url,
|
||||
token_url: Url,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||
#[serde(untagged)]
|
||||
pub enum MaybeRef<T> {
|
||||
Value {
|
||||
#[serde(flatten)]
|
||||
value: T,
|
||||
},
|
||||
Ref {
|
||||
#[serde(rename = "$ref")]
|
||||
_ref: String,
|
||||
}
|
||||
}
|
24321
swagger.v1.json
Normal file
24321
swagger.v1.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue