pull in the most recent typify (#44)

change symbol sanitization accordingly (use heck rather than convert_case)
fix: OpenAPI -> JSON Schema conversion was losing title and docs
remove assert that there are no tag (but still ignore them)
This commit is contained in:
Adam Leventhal 2022-05-09 17:30:08 -07:00 committed by GitHub
parent bbf81dfe7d
commit 7f1b98f7b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 155 additions and 77 deletions

66
Cargo.lock generated
View File

@ -150,10 +150,19 @@ dependencies = [
]
[[package]]
name = "convert_case"
version = "0.4.0"
name = "console"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"regex",
"terminal_size",
"unicode-width",
"winapi",
]
[[package]]
name = "core-foundation"
@ -191,12 +200,6 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]]
name = "digest"
version = "0.8.1"
@ -304,6 +307,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encoding_rs"
version = "0.8.30"
@ -340,12 +349,13 @@ dependencies = [
[[package]]
name = "expectorate"
version = "1.0.4"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "804d601ea8a13ddbecf5ab4b6cf75b5d6d0539479c6fb2aea1596e352a5ee27e"
checksum = "5d9b457178b54cf0321a39fb6643ad7b9c705cf483ad4fb6d6092054e9ce839e"
dependencies = [
"difference",
"console",
"newline-converter",
"similar",
]
[[package]]
@ -537,6 +547,12 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
version = "0.1.19"
@ -1039,10 +1055,10 @@ dependencies = [
name = "progenitor-impl"
version = "0.0.0"
dependencies = [
"convert_case",
"dropshot",
"expectorate",
"getopts",
"heck",
"http",
"hyper",
"indexmap",
@ -1412,6 +1428,12 @@ dependencies = [
"libc",
]
[[package]]
name = "similar"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
[[package]]
name = "slab"
version = "0.4.5"
@ -1549,6 +1571,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.30"
@ -1761,7 +1793,7 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "typify"
version = "0.0.6-dev"
source = "git+https://github.com/oxidecomputer/typify#8316b7d227eeec59d854279e947b1882ae2c635a"
source = "git+https://github.com/oxidecomputer/typify#4494446aac57ad0841f0d91ba0a9c1acca5de228"
dependencies = [
"typify-impl",
"typify-macro",
@ -1770,9 +1802,9 @@ dependencies = [
[[package]]
name = "typify-impl"
version = "0.0.6-dev"
source = "git+https://github.com/oxidecomputer/typify#8316b7d227eeec59d854279e947b1882ae2c635a"
source = "git+https://github.com/oxidecomputer/typify#4494446aac57ad0841f0d91ba0a9c1acca5de228"
dependencies = [
"convert_case",
"heck",
"log",
"proc-macro2",
"quote",
@ -1787,7 +1819,7 @@ dependencies = [
[[package]]
name = "typify-macro"
version = "0.0.6-dev"
source = "git+https://github.com/oxidecomputer/typify#8316b7d227eeec59d854279e947b1882ae2c635a"
source = "git+https://github.com/oxidecomputer/typify#4494446aac57ad0841f0d91ba0a9c1acca5de228"
dependencies = [
"proc-macro2",
"quote",

View File

@ -7,7 +7,7 @@ repository = "https://github.com/oxidecomputer/progenitor.git"
description = "An OpenAPI client generator - core implementation"
[dependencies]
convert_case = "0.4"
heck = "0.4.0"
getopts = "0.2"
indexmap = "1.7"
openapiv3 = "1.0.0"

View File

@ -5,13 +5,16 @@ use std::{
collections::{BTreeSet, HashMap},
};
use convert_case::Case;
use openapiv3::{Components, Response, StatusCode};
use proc_macro2::TokenStream;
use quote::{format_ident, quote, ToTokens};
use typify::TypeId;
use crate::{template::PathTemplate, util::sanitize, Error, Generator, Result};
use crate::{
template::PathTemplate,
util::{sanitize, Case},
Error, Generator, Result,
};
use crate::{to_schema::ToSchema, util::ReferenceOrExt};
pub(crate) struct OperationMethod {

View File

@ -120,6 +120,7 @@ impl Convert<schemars::schema::Schema> for openapiv3::Schema {
};
let metadata = Some(Box::new(metadata)).reduce();
let extensions = extensions.into_iter().collect();
match &self.schema_kind {
openapiv3::SchemaKind::Type(openapiv3::Type::String(
@ -144,7 +145,7 @@ impl Convert<schemars::schema::Schema> for openapiv3::Schema {
pattern: pattern.clone(),
}))
.reduce(),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
},
openapiv3::SchemaKind::Type(openapiv3::Type::Number(
@ -188,7 +189,7 @@ impl Convert<schemars::schema::Schema> for openapiv3::Schema {
},
))
.reduce(),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
}
}
@ -236,7 +237,7 @@ impl Convert<schemars::schema::Schema> for openapiv3::Schema {
},
))
.reduce(),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
}
}
@ -265,7 +266,7 @@ impl Convert<schemars::schema::Schema> for openapiv3::Schema {
property_names: None,
}))
.reduce(),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
},
@ -295,7 +296,7 @@ impl Convert<schemars::schema::Schema> for openapiv3::Schema {
contains: None,
}))
.reduce(),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
},
@ -306,59 +307,63 @@ impl Convert<schemars::schema::Schema> for openapiv3::Schema {
schemars::schema::InstanceType::Boolean,
nullable,
),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
}
}
openapiv3::SchemaKind::OneOf { one_of } => {
schemars::schema::SchemaObject {
metadata,
subschemas: Some(Box::new(
schemars::schema::SubschemaValidation {
one_of: Some(one_of.convert()),
..Default::default()
},
)),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
}
}
openapiv3::SchemaKind::AllOf { all_of } => {
schemars::schema::SchemaObject {
metadata,
subschemas: Some(Box::new(
schemars::schema::SubschemaValidation {
all_of: Some(all_of.convert()),
..Default::default()
},
)),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
}
}
openapiv3::SchemaKind::AnyOf { any_of } => {
schemars::schema::SchemaObject {
metadata,
subschemas: Some(Box::new(
schemars::schema::SubschemaValidation {
any_of: Some(any_of.convert()),
..Default::default()
},
)),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
}
}
openapiv3::SchemaKind::Not { not } => {
schemars::schema::SchemaObject {
metadata,
subschemas: Some(Box::new(
schemars::schema::SubschemaValidation {
not: Some(Box::new(not.convert())),
..Default::default()
},
)),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
}
}
@ -396,10 +401,11 @@ impl Convert<schemars::schema::Schema> for openapiv3::Schema {
&& all_of.is_empty()
&& any_of.is_empty() =>
{
let mut schema =
schemars::schema::Schema::Bool(true).into_object();
schema.extensions = extensions.into_iter().collect();
schema
schemars::schema::SchemaObject {
metadata,
extensions,
..schemars::schema::Schema::Bool(true).into_object()
}
}
// A simple null value.
@ -441,7 +447,7 @@ impl Convert<schemars::schema::Schema> for openapiv3::Schema {
instance_type: Some(
schemars::schema::InstanceType::Null.into(),
),
extensions: extensions.into_iter().collect(),
extensions,
..Default::default()
}
}

View File

@ -1,6 +1,5 @@
// Copyright 2022 Oxide Computer Company
use convert_case::{Case, Casing};
use indexmap::IndexMap;
use openapiv3::{
Components, Parameter, ReferenceOr, RequestBody, Response, Schema,
@ -65,14 +64,30 @@ impl ComponentLookup for Schema {
}
}
pub(crate) enum Case {
Pascal,
Snake,
}
pub(crate) fn sanitize(input: &str, case: Case) -> String {
let out = input
.replace("'", "")
.replace(|c: char| !c.is_xid_continue(), "-")
.to_case(case);
use heck::{ToPascalCase, ToSnakeCase};
let to_case = match case {
Case::Pascal => str::to_pascal_case,
Case::Snake => str::to_snake_case,
};
// If every case was special then none of them would be.
let out = match input {
"+1" => "plus1".to_string(),
"-1" => "minus1".to_string(),
_ => to_case(
&input
.replace("'", "")
.replace(|c: char| !c.is_xid_continue(), "-"),
),
};
let out = match out.chars().next() {
None => "x".to_case(case),
None => to_case("x"),
Some(c) if c.is_xid_start() => out,
Some(_) => format!("_{}", out),
};

View File

@ -49,6 +49,7 @@ pub mod types {
pub device_path: String,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
pub project_id: uuid::Uuid,
pub size: ByteCount,
@ -66,6 +67,7 @@ pub mod types {
pub struct DiskCreate {
pub description: String,
pub name: Name,
#[doc = "size of the Disk"]
pub size: ByteCount,
#[doc = "id for snapshot from which the Disk should be created, if any"]
#[serde(default, skip_serializing_if = "Option::is_none")]
@ -88,6 +90,7 @@ pub mod types {
pub next_page: Option<String>,
}
#[doc = "State of a Disk (primarily: attached or not)"]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "state", content = "instance")]
pub enum DiskState {
@ -186,8 +189,11 @@ pub mod types {
pub hostname: String,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "memory allocated for this Instance"]
pub memory: ByteCount,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "number of CPUs allocated for this Instance"]
pub ncpus: InstanceCpuCount,
#[doc = "id for the project containing this Instance"]
pub project_id: uuid::Uuid,
@ -217,6 +223,7 @@ pub mod types {
pub memory: ByteCount,
pub name: Name,
pub ncpus: InstanceCpuCount,
#[doc = "The network interfaces to be created for this instance."]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub network_interfaces: Option<InstanceNetworkInterfaceAttachment>,
}
@ -227,6 +234,7 @@ pub mod types {
pub dst_sled_uuid: uuid::Uuid,
}
#[doc = "Describes an attachment of a `NetworkInterface` to an `Instance`, at the time the instance is created."]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type", content = "params")]
pub enum InstanceNetworkInterfaceAttachment {
@ -292,6 +300,7 @@ pub mod types {
}
}
#[doc = "An `IpNet` represents an IP network, either IPv4 or IPv6."]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum IpNet {
V4(Ipv4Net),
@ -400,7 +409,9 @@ pub mod types {
pub instance_id: uuid::Uuid,
#[doc = "The IP address assigned to this interface."]
pub ip: String,
#[doc = "The MAC address assigned to this interface."]
pub mac: MacAddr,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "The subnet to which the interface belongs."]
pub subnet_id: uuid::Uuid,
@ -420,7 +431,9 @@ pub mod types {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ip: Option<String>,
pub name: Name,
#[doc = "The VPC Subnet in which to create the interface."]
pub subnet_name: Name,
#[doc = "The VPC in which to create the interface."]
pub vpc_name: Name,
}
@ -441,6 +454,7 @@ pub mod types {
pub description: String,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "timestamp when this resource was created"]
pub time_created: chrono::DateTime<chrono::offset::Utc>,
@ -481,6 +495,7 @@ pub mod types {
pub description: String,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
pub organization_id: uuid::Uuid,
#[doc = "timestamp when this resource was created"]
@ -522,6 +537,7 @@ pub mod types {
pub description: String,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "timestamp when this resource was created"]
pub time_created: chrono::DateTime<chrono::offset::Utc>,
@ -566,6 +582,7 @@ pub mod types {
pub next_page: Option<String>,
}
#[doc = "A `RouteDestination` is used to match traffic with a routing rule, on the destination of that traffic.\n\nWhen traffic is to be sent to a destination that is within a given `RouteDestination`, the corresponding [`RouterRoute`] applies, and traffic will be forward to the [`RouteTarget`] for that rule."]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type", content = "value")]
pub enum RouteDestination {
@ -579,6 +596,7 @@ pub mod types {
Subnet(Name),
}
#[doc = "A `RouteTarget` describes the possible locations that traffic matching a route destination can be sent."]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type", content = "value")]
pub enum RouteTarget {
@ -602,7 +620,9 @@ pub mod types {
pub destination: RouteDestination,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "Describes the kind of router. Set at creation. `read-only`"]
pub kind: RouterRouteKind,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "The VPC Router to which the route belongs."]
pub router_id: uuid::Uuid,
@ -725,6 +745,7 @@ pub mod types {
pub description: String,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
pub service_address: String,
#[doc = "timestamp when this resource was created"]
@ -751,6 +772,7 @@ pub mod types {
pub disk_id: uuid::Uuid,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
pub project_id: uuid::Uuid,
pub size: ByteCount,
@ -764,6 +786,7 @@ pub mod types {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SnapshotCreate {
pub description: String,
#[doc = "The name of the disk to be snapshotted"]
pub disk: Name,
pub name: Name,
}
@ -814,6 +837,7 @@ pub mod types {
pub description: String,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "timestamp when this resource was created"]
pub time_created: chrono::DateTime<chrono::offset::Utc>,
@ -836,11 +860,13 @@ pub mod types {
pub struct Vpc {
#[doc = "human-readable free-form text about a resource"]
pub description: String,
#[doc = "The name used for the VPC in DNS."]
pub dns_name: Name,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[serde(rename = "ipv6_prefix")]
pub ipv_6_prefix: Ipv6Net,
#[doc = "The unique local IPv6 address range for subnets in this VPC"]
pub ipv6_prefix: Ipv6Net,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "id for the project containing this VPC"]
pub project_id: uuid::Uuid,
@ -857,28 +883,30 @@ pub mod types {
pub struct VpcCreate {
pub description: String,
pub dns_name: Name,
#[serde(
rename = "ipv6_prefix",
default,
skip_serializing_if = "Option::is_none"
)]
pub ipv_6_prefix: Option<Ipv6Net>,
#[doc = "The IPv6 prefix for this VPC.\n\nAll IPv6 subnets created from this VPC must be taken from this range, which sould be a Unique Local Address in the range `fd00::/48`. The default VPC Subnet will have the first `/64` range from this prefix."]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ipv6_prefix: Option<Ipv6Net>,
pub name: Name,
}
#[doc = "A single rule in a VPC firewall"]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VpcFirewallRule {
#[doc = "whether traffic matching the rule should be allowed or dropped"]
pub action: VpcFirewallRuleAction,
#[doc = "human-readable free-form text about a resource"]
pub description: String,
#[doc = "whether this rule is for incoming or outgoing traffic"]
pub direction: VpcFirewallRuleDirection,
#[doc = "reductions on the scope of the rule"]
pub filters: VpcFirewallRuleFilter,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "the relative priority of this rule"]
pub priority: u16,
#[doc = "whether this rule is in effect"]
pub status: VpcFirewallRuleStatus,
#[doc = "list of sets of instances that the rule applies to"]
pub targets: Vec<VpcFirewallRuleTarget>,
@ -938,6 +966,7 @@ pub mod types {
pub protocols: Option<Vec<VpcFirewallRuleProtocol>>,
}
#[doc = "The `VpcFirewallRuleHostFilter` is used to filter traffic on the basis of its source or destination host."]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type", content = "value")]
pub enum VpcFirewallRuleHostFilter {
@ -991,6 +1020,7 @@ pub mod types {
}
}
#[doc = "A `VpcFirewallRuleTarget` is used to specify the set of [`Instance`]s to which a firewall rule applies."]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type", content = "value")]
pub enum VpcFirewallRuleTarget {
@ -1009,14 +1039,19 @@ pub mod types {
#[doc = "A single rule in a VPC firewall"]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VpcFirewallRuleUpdate {
#[doc = "whether traffic matching the rule should be allowed or dropped"]
pub action: VpcFirewallRuleAction,
#[doc = "human-readable free-form text about a resource"]
pub description: String,
#[doc = "whether this rule is for incoming or outgoing traffic"]
pub direction: VpcFirewallRuleDirection,
#[doc = "reductions on the scope of the rule"]
pub filters: VpcFirewallRuleFilter,
#[doc = "name of the rule, unique to this VPC"]
pub name: Name,
#[doc = "the relative priority of this rule"]
pub priority: u16,
#[doc = "whether this rule is in effect"]
pub status: VpcFirewallRuleStatus,
#[doc = "list of sets of instances that the rule applies to"]
pub targets: Vec<VpcFirewallRuleTarget>,
@ -1052,6 +1087,7 @@ pub mod types {
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
pub kind: VpcRouterKind,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "timestamp when this resource was created"]
pub time_created: chrono::DateTime<chrono::offset::Utc>,
@ -1111,10 +1147,11 @@ pub mod types {
pub description: String,
#[doc = "unique, immutable, system-controlled identifier for each resource"]
pub id: uuid::Uuid,
#[serde(rename = "ipv4_block")]
pub ipv_4_block: Ipv4Net,
#[serde(rename = "ipv6_block")]
pub ipv_6_block: Ipv6Net,
#[doc = "The IPv4 subnet CIDR block."]
pub ipv4_block: Ipv4Net,
#[doc = "The IPv6 subnet CIDR block."]
pub ipv6_block: Ipv6Net,
#[doc = "unique, mutable, user-controlled identifier for each resource"]
pub name: Name,
#[doc = "timestamp when this resource was created"]
pub time_created: chrono::DateTime<chrono::offset::Utc>,
@ -1128,14 +1165,11 @@ pub mod types {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VpcSubnetCreate {
pub description: String,
#[serde(rename = "ipv4_block")]
pub ipv_4_block: Ipv4Net,
#[serde(
rename = "ipv6_block",
default,
skip_serializing_if = "Option::is_none"
)]
pub ipv_6_block: Option<Ipv6Net>,
#[doc = "The IPv4 address range for this subnet.\n\nIt must be allocated from an RFC 1918 private address range, and must not overlap with any other existing subnet in the VPC."]
pub ipv4_block: Ipv4Net,
#[doc = "The IPv6 address range for this subnet.\n\nIt must be allocated from the RFC 4193 Unique Local Address range, with the prefix equal to the parent VPC's prefix. A random `/64` block will be assigned if one is not provided. It must not overlap with any existing subnet in the VPC."]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ipv6_block: Option<Ipv6Net>,
pub name: Name,
}
@ -1154,18 +1188,10 @@ pub mod types {
pub struct VpcSubnetUpdate {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(
rename = "ipv4_block",
default,
skip_serializing_if = "Option::is_none"
)]
pub ipv_4_block: Option<Ipv4Net>,
#[serde(
rename = "ipv6_block",
default,
skip_serializing_if = "Option::is_none"
)]
pub ipv_6_block: Option<Ipv6Net>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ipv4_block: Option<Ipv4Net>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ipv6_block: Option<Ipv6Net>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<Name>,
}

View File

@ -166,10 +166,6 @@ where
bail!("security not presently supported");
}
if !api.tags.is_empty() {
bail!("tags not presently supported");
}
let mut opids = HashSet::new();
for p in api.paths.paths.iter() {
match p.1 {