From c0bcfacc5c8661a1d0a643e99635ecc748a9af5a Mon Sep 17 00:00:00 2001 From: "Adam H. Leventhal" Date: Thu, 6 Jan 2022 23:19:45 -0800 Subject: [PATCH 1/2] JsonSchema --- Cargo.lock | 9 +- progenitor-impl/Cargo.toml | 4 +- progenitor-impl/src/lib.rs | 1 + progenitor-impl/tests/output/buildomat.out | 39 +++-- progenitor-impl/tests/output/keeper.out | 21 +-- progenitor-impl/tests/output/nexus.out | 193 ++++++++++++--------- progenitor/Cargo.toml | 1 + 7 files changed, 151 insertions(+), 117 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 078afe03b..06c4eff24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -665,6 +665,7 @@ dependencies = [ "progenitor-impl", "progenitor-macro", "reqwest", + "schemars", "serde", "serde_json", "uuid", @@ -872,10 +873,12 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271ac0c667b8229adf70f0f957697c96fafd7486ab7481e15dc5e45e3e6a4368" dependencies = [ + "chrono", "dyn-clone", "schemars_derive", "serde", "serde_json", + "uuid", ] [[package]] @@ -1158,7 +1161,7 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "typify" version = "0.0.6-dev" -source = "git+https://github.com/oxidecomputer/typify#df983c2981fc055efeba3fc360e724221703d4bd" +source = "git+https://github.com/oxidecomputer/typify?branch=json-schema#0be9b35a5007e3f797e43ce41eba03dcee63e503" dependencies = [ "typify-impl", "typify-macro", @@ -1167,7 +1170,7 @@ dependencies = [ [[package]] name = "typify-impl" version = "0.0.6-dev" -source = "git+https://github.com/oxidecomputer/typify#df983c2981fc055efeba3fc360e724221703d4bd" +source = "git+https://github.com/oxidecomputer/typify?branch=json-schema#0be9b35a5007e3f797e43ce41eba03dcee63e503" dependencies = [ "convert_case", "log", @@ -1183,7 +1186,7 @@ dependencies = [ [[package]] name = "typify-macro" version = "0.0.6-dev" -source = "git+https://github.com/oxidecomputer/typify#df983c2981fc055efeba3fc360e724221703d4bd" +source = "git+https://github.com/oxidecomputer/typify?branch=json-schema#0be9b35a5007e3f797e43ce41eba03dcee63e503" dependencies = [ "proc-macro2", "quote", diff --git a/progenitor-impl/Cargo.toml b/progenitor-impl/Cargo.toml index a12fd24a9..6ff6c2d43 100644 --- a/progenitor-impl/Cargo.toml +++ b/progenitor-impl/Cargo.toml @@ -15,11 +15,11 @@ proc-macro2 = "1.0" quote = "1.0" regex = "1.5" rustfmt-wrapper = "0.1" -schemars = "0.8" +schemars = { version = "0.8", features = [ "chrono", "uuid" ] } serde = { version = "1.0", features = [ "derive" ] } serde_json = "1.0" convert_case = "0.4" -typify = { git = "https://github.com/oxidecomputer/typify" } +typify = { git = "https://github.com/oxidecomputer/typify", branch = "json-schema" } thiserror = "1.0" [dev-dependencies] diff --git a/progenitor-impl/src/lib.rs b/progenitor-impl/src/lib.rs index cdd295b7f..85f88c3db 100644 --- a/progenitor-impl/src/lib.rs +++ b/progenitor-impl/src/lib.rs @@ -194,6 +194,7 @@ impl Generator { } pub mod types { + use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #(#types)* } diff --git a/progenitor-impl/tests/output/buildomat.out b/progenitor-impl/tests/output/buildomat.out index 591fcc12d..1b1305983 100644 --- a/progenitor-impl/tests/output/buildomat.out +++ b/progenitor-impl/tests/output/buildomat.out @@ -19,8 +19,9 @@ mod progenitor_support { } pub mod types { + use schemars::JsonSchema; use serde::{Deserialize, Serialize}; - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Task { pub id: String, pub name: String, @@ -29,7 +30,7 @@ pub mod types { pub state: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct TaskEvent { pub payload: String, pub seq: u32, @@ -37,14 +38,14 @@ pub mod types { pub time: chrono::DateTime, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct TaskOutput { pub id: String, pub path: String, pub size: u64, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct TaskSubmit { pub name: String, #[serde(default, skip_serializing_if = "Vec::is_empty")] @@ -52,35 +53,35 @@ pub mod types { pub script: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct TaskSubmitResult { pub id: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct UploadedChunk { pub id: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct UserCreate { pub name: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct UserCreateResult { pub id: String, pub name: String, pub token: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WhoamiResult { pub id: String, pub name: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Worker { pub deleted: bool, pub id: String, @@ -92,58 +93,58 @@ pub mod types { pub tasks: Vec, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WorkerAddOutput { pub chunks: Vec, pub path: String, pub size: i64, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WorkerAppendTask { pub payload: String, pub stream: String, pub time: chrono::DateTime, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WorkerBootstrap { pub bootstrap: String, pub token: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WorkerBootstrapResult { pub id: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WorkerCompleteTask { pub failed: bool, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WorkerPingResult { pub poweroff: bool, #[serde(default, skip_serializing_if = "Option::is_none")] pub task: Option, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WorkerPingTask { pub id: String, pub output_rules: Vec, pub script: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WorkerTask { pub id: String, pub name: String, pub owner: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct WorkersResult { pub workers: Vec, } diff --git a/progenitor-impl/tests/output/keeper.out b/progenitor-impl/tests/output/keeper.out index fc9d17962..e38bbe5f7 100644 --- a/progenitor-impl/tests/output/keeper.out +++ b/progenitor-impl/tests/output/keeper.out @@ -19,32 +19,33 @@ mod progenitor_support { } pub mod types { + use schemars::JsonSchema; use serde::{Deserialize, Serialize}; - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct EnrolBody { pub host: String, pub key: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct GlobalJobsResult { pub summary: Vec, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct OutputRecord { pub msg: String, pub stream: String, pub time: chrono::DateTime, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct PingResult { pub host: String, pub ok: bool, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ReportFinishBody { pub duration_millis: i32, pub end_time: chrono::DateTime, @@ -52,7 +53,7 @@ pub mod types { pub id: ReportId, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ReportId { pub host: String, pub job: String, @@ -61,25 +62,25 @@ pub mod types { pub uuid: String, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ReportOutputBody { pub id: ReportId, pub record: OutputRecord, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ReportResult { pub existed_already: bool, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ReportStartBody { pub id: ReportId, pub script: String, pub start_time: chrono::DateTime, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ReportSummary { pub age_seconds: i32, pub duration_seconds: i32, diff --git a/progenitor-impl/tests/output/nexus.out b/progenitor-impl/tests/output/nexus.out index bd4ca7438..dcb635bd3 100644 --- a/progenitor-impl/tests/output/nexus.out +++ b/progenitor-impl/tests/output/nexus.out @@ -19,9 +19,10 @@ mod progenitor_support { } pub mod types { + use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #[doc = "A count of bytes, typically used either for memory or storage capacity\n\nThe maximum supported byte count is [`i64::MAX`]. This makes it somewhat inconvenient to define constructors: a u32 constructor can be infallible, but an i64 constructor can fail (if the value is negative) and a u64 constructor can fail (if the value is larger than i64::MAX). We provide all of these for consumers' convenience."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ByteCount(pub u64); impl std::ops::Deref for ByteCount { type Target = u64; @@ -31,7 +32,9 @@ pub mod types { } #[doc = "The type of an individual datum of a metric."] - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum DatumType { Bool, I64, @@ -61,7 +64,7 @@ pub mod types { } #[doc = "Client view of an [`Disk`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Disk { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -89,7 +92,7 @@ pub mod types { } #[doc = "Create-time parameters for a [`Disk`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct DiskCreate { pub description: String, pub name: Name, @@ -104,13 +107,13 @@ pub mod types { } #[doc = "Parameters for the [`Disk`] to be attached or detached to an instance"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct DiskIdentifier { pub disk: Name, } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct DiskResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -119,7 +122,7 @@ pub mod types { pub next_page: Option, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] #[serde(tag = "state", content = "instance")] pub enum DiskState { #[serde(rename = "creating")] @@ -139,7 +142,7 @@ pub mod types { } #[doc = "The name and type information for a field of a timeseries schema."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct FieldSchema { pub name: String, pub source: FieldSource, @@ -147,7 +150,9 @@ pub mod types { } #[doc = "The source from which a field is derived, the target or metric."] - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum FieldSource { Target, Metric, @@ -163,7 +168,9 @@ pub mod types { } #[doc = "The `FieldType` identifies the data type of a target or metric field."] - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum FieldType { String, I64, @@ -185,7 +192,9 @@ pub mod types { } #[doc = "Supported set of sort modes for scanning by id only.\n\nCurrently, we only support scanning in ascending order."] - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum IdSortMode { #[serde(rename = "id-ascending")] IdAscending, @@ -200,7 +209,7 @@ pub mod types { } #[doc = "Identity-related metadata that's included in nearly all public API objects"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct IdentityMetadata { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -216,7 +225,7 @@ pub mod types { } #[doc = "Client view of an [`Instance`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Instance { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -243,7 +252,7 @@ pub mod types { } #[doc = "The number of CPUs in an Instance"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct InstanceCpuCount(pub u16); impl std::ops::Deref for InstanceCpuCount { type Target = u16; @@ -253,7 +262,7 @@ pub mod types { } #[doc = "Create-time parameters for an [`Instance`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct InstanceCreate { pub description: String, pub hostname: String, @@ -263,7 +272,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct InstanceResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -273,7 +282,9 @@ pub mod types { } #[doc = "Running state of an Instance (primarily: booted or stopped)\n\nThis typically reflects whether it's starting, running, stopping, or stopped, but also includes states related to the Instance's lifecycle"] - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum InstanceState { #[serde(rename = "creating")] Creating, @@ -312,7 +323,7 @@ pub mod types { } #[doc = "An IPv4 subnet, including prefix and subnet mask"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Ipv4Net(pub String); impl std::ops::Deref for Ipv4Net { type Target = String; @@ -322,7 +333,7 @@ pub mod types { } #[doc = "An IPv6 subnet, including prefix and subnet mask"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Ipv6Net(pub String); impl std::ops::Deref for Ipv6Net { type Target = String; @@ -332,7 +343,7 @@ pub mod types { } #[doc = "An inclusive-inclusive range of IP ports. The second port may be omitted to represent a single port"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct L4PortRange(pub String); impl std::ops::Deref for L4PortRange { type Target = String; @@ -341,13 +352,13 @@ pub mod types { } } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct LoginParams { pub username: String, } #[doc = "A Media Access Control address, in EUI-48 format"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct MacAddr(pub String); impl std::ops::Deref for MacAddr { type Target = String; @@ -357,7 +368,7 @@ pub mod types { } #[doc = "Names must begin with a lower case ASCII letter, be composed exclusively of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end with a '-'."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Name(pub String); impl std::ops::Deref for Name { type Target = String; @@ -367,7 +378,9 @@ pub mod types { } #[doc = "Supported set of sort modes for scanning by name or id"] - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum NameOrIdSortMode { #[serde(rename = "name-ascending")] NameAscending, @@ -388,7 +401,9 @@ pub mod types { } #[doc = "Supported set of sort modes for scanning by name only\n\nCurrently, we only support scanning in ascending order."] - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum NameSortMode { #[serde(rename = "name-ascending")] NameAscending, @@ -403,7 +418,7 @@ pub mod types { } #[doc = "A `NetworkInterface` represents a virtual network interface device."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct NetworkInterface { pub identity: IdentityMetadata, #[doc = "The Instance to which the interface belongs."] @@ -418,7 +433,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct NetworkInterfaceResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -428,7 +443,7 @@ pub mod types { } #[doc = "Client view of an [`Organization`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Organization { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -444,14 +459,14 @@ pub mod types { } #[doc = "Create-time parameters for an [`Organization`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct OrganizationCreate { pub description: String, pub name: Name, } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct OrganizationResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -461,7 +476,7 @@ pub mod types { } #[doc = "Updateable properties of an [`Organization`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct OrganizationUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -470,7 +485,7 @@ pub mod types { } #[doc = "Client view of a [`Project`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Project { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -488,14 +503,14 @@ pub mod types { } #[doc = "Create-time parameters for a [`Project`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ProjectCreate { pub description: String, pub name: Name, } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ProjectResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -505,7 +520,7 @@ pub mod types { } #[doc = "Updateable properties of a [`Project`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct ProjectUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -514,13 +529,13 @@ pub mod types { } #[doc = "Client view of an [`Rack`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Rack { pub identity: IdentityMetadata, } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct RackResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -530,14 +545,14 @@ pub mod types { } #[doc = "Client view of a [`Role`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Role { pub description: String, pub name: RoleName, } #[doc = "Role names consist of two string components separated by dot (\".\")."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct RoleName(pub String); impl std::ops::Deref for RoleName { type Target = String; @@ -547,7 +562,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct RoleResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -556,7 +571,7 @@ pub mod types { pub next_page: Option, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] #[serde(tag = "type", content = "value")] pub enum RouteDestination { #[serde(rename = "ip")] @@ -567,7 +582,7 @@ pub mod types { Subnet(Name), } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] #[serde(tag = "type", content = "value")] pub enum RouteTarget { #[serde(rename = "ip")] @@ -583,7 +598,7 @@ pub mod types { } #[doc = "A route defines a rule that governs where traffic should be sent based on its destination."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct RouterRoute { pub destination: RouteDestination, pub identity: IdentityMetadata, @@ -594,7 +609,7 @@ pub mod types { } #[doc = "Create-time parameters for a [`RouterRoute`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct RouterRouteCreateParams { pub description: String, pub destination: RouteDestination, @@ -603,7 +618,9 @@ pub mod types { } #[doc = "The classification of a [`RouterRoute`] as defined by the system. The kind determines certain attributes such as if the route is modifiable and describes how or where the route was created.\n\nSee [RFD-21](https://rfd.shared.oxide.computer/rfd/0021#concept-router) for more context"] - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum RouterRouteKind { Default, VpcSubnet, @@ -623,7 +640,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct RouterRouteResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -633,7 +650,7 @@ pub mod types { } #[doc = "Updateable properties of a [`RouterRoute`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct RouterRouteUpdateParams { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -643,13 +660,13 @@ pub mod types { pub target: RouteTarget, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Saga { pub id: uuid::Uuid, pub state: SagaState, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] #[serde(tag = "error")] pub enum SagaErrorInfo { #[serde(rename = "actionFailed")] @@ -665,7 +682,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct SagaResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -674,7 +691,7 @@ pub mod types { pub next_page: Option, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] #[serde(tag = "state")] pub enum SagaState { #[serde(rename = "running")] @@ -689,7 +706,7 @@ pub mod types { } #[doc = "Client view of an [`Sled`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Sled { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -707,7 +724,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct SledResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -717,7 +734,7 @@ pub mod types { } #[doc = "Names are constructed by concatenating the target and metric names with ':'. Target and metric names must be lowercase alphanumeric characters with '_' separating words."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct TimeseriesName(pub String); impl std::ops::Deref for TimeseriesName { type Target = String; @@ -727,7 +744,7 @@ pub mod types { } #[doc = "The schema for a timeseries.\n\nThis includes the name of the timeseries, as well as the datum type of its metric and the schema for each field."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct TimeseriesSchema { pub created: chrono::DateTime, pub datum_type: DatumType, @@ -736,7 +753,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct TimeseriesSchemaResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -746,7 +763,7 @@ pub mod types { } #[doc = "Client view of a [`User`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct User { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -762,7 +779,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct UserResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -772,7 +789,7 @@ pub mod types { } #[doc = "Client view of a [`Vpc`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct Vpc { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -796,7 +813,7 @@ pub mod types { } #[doc = "Create-time parameters for a [`Vpc`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcCreate { pub description: String, #[serde(rename = "dnsName")] @@ -805,7 +822,7 @@ pub mod types { } #[doc = "A single rule in a VPC firewall"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcFirewallRule { pub action: VpcFirewallRuleAction, pub direction: VpcFirewallRuleDirection, @@ -818,7 +835,9 @@ pub mod types { pub targets: Vec, } - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum VpcFirewallRuleAction { #[serde(rename = "allow")] Allow, @@ -835,7 +854,9 @@ pub mod types { } } - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum VpcFirewallRuleDirection { #[serde(rename = "inbound")] Inbound, @@ -853,7 +874,7 @@ pub mod types { } #[doc = "Filter for a firewall rule. A given packet must match every field that is present for the rule to apply to it. A packet matches a field if any entry in that field matches the packet."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcFirewallRuleFilter { #[doc = "If present, the sources (if incoming) or destinations (if outgoing) this rule applies to."] #[serde(default, skip_serializing_if = "Option::is_none")] @@ -866,7 +887,7 @@ pub mod types { pub protocols: Option>, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] #[serde(tag = "type", content = "value")] pub enum VpcFirewallRuleHostFilter { #[serde(rename = "vpc")] @@ -882,7 +903,9 @@ pub mod types { } #[doc = "The protocols that may be specified in a firewall rule's filter"] - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum VpcFirewallRuleProtocol { #[serde(rename = "TCP")] Tcp, @@ -903,7 +926,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcFirewallRuleResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -912,7 +935,9 @@ pub mod types { pub next_page: Option, } - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum VpcFirewallRuleStatus { #[serde(rename = "disabled")] Disabled, @@ -929,7 +954,7 @@ pub mod types { } } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] #[serde(tag = "type", content = "value")] pub enum VpcFirewallRuleTarget { #[serde(rename = "vpc")] @@ -941,7 +966,7 @@ pub mod types { } #[doc = "A single rule in a VPC firewall"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcFirewallRuleUpdate { pub action: VpcFirewallRuleAction, #[doc = "human-readable free-form text about a resource"] @@ -955,7 +980,7 @@ pub mod types { pub targets: Vec, } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcFirewallRuleUpdateParams( pub std::collections::HashMap, ); @@ -966,7 +991,7 @@ pub mod types { } } - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcFirewallRuleUpdateResult(pub std::collections::HashMap); impl std::ops::Deref for VpcFirewallRuleUpdateResult { type Target = std::collections::HashMap; @@ -976,7 +1001,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -986,7 +1011,7 @@ pub mod types { } #[doc = "A VPC router defines a series of rules that indicate where traffic should be sent depending on its destination."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcRouter { pub identity: IdentityMetadata, pub kind: VpcRouterKind, @@ -995,13 +1020,15 @@ pub mod types { } #[doc = "Create-time parameters for a [`VpcRouter`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcRouterCreate { pub description: String, pub name: Name, } - #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] + #[derive( + Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, + )] pub enum VpcRouterKind { #[serde(rename = "system")] System, @@ -1019,7 +1046,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcRouterResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -1029,7 +1056,7 @@ pub mod types { } #[doc = "Updateable properties of a [`VpcRouter`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcRouterUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -1038,7 +1065,7 @@ pub mod types { } #[doc = "A VPC subnet represents a logical grouping for instances that allows network traffic between them, within a IPv4 subnetwork or optionall an IPv6 subnetwork."] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcSubnet { pub identity: IdentityMetadata, #[serde( @@ -1058,7 +1085,7 @@ pub mod types { } #[doc = "Create-time parameters for a [`VpcSubnet`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcSubnetCreate { pub description: String, #[serde(rename = "ipv4Block", default, skip_serializing_if = "Option::is_none")] @@ -1069,7 +1096,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcSubnetResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -1079,7 +1106,7 @@ pub mod types { } #[doc = "Updateable properties of a [`VpcSubnet`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcSubnetUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -1092,7 +1119,7 @@ pub mod types { } #[doc = "Updateable properties of a [`Vpc`]"] - #[derive(Serialize, Deserialize, Debug, Clone)] + #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] pub struct VpcUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, diff --git a/progenitor/Cargo.toml b/progenitor/Cargo.toml index a7490fccd..83437a12b 100644 --- a/progenitor/Cargo.toml +++ b/progenitor/Cargo.toml @@ -20,4 +20,5 @@ chrono = { version = "0.4", features = ["serde"] } futures = "0.3" percent-encoding = "2.1" reqwest = { version = "0.11", features = ["json", "stream"] } +schemars = "0.8" uuid = { version = "0.8", features = ["serde", "v4"] } From b246e5a2db4db0cabcdcc5661cd76e06e3efa7b0 Mon Sep 17 00:00:00 2001 From: "Adam H. Leventhal" Date: Thu, 13 Jan 2022 15:07:24 -0800 Subject: [PATCH 2/2] generic mechanism for adding extra derives structured generate_api! macro general updates and cleanup --- Cargo.lock | 217 ++++++++++----------- Cargo.toml | 6 +- example-build/Cargo.toml | 4 +- example-macro/Cargo.toml | 7 +- example-macro/src/main.rs | 19 +- progenitor-impl/Cargo.toml | 6 +- progenitor-impl/src/lib.rs | 8 +- progenitor-impl/tests/output/buildomat.out | 39 ++-- progenitor-impl/tests/output/keeper.out | 21 +- progenitor-impl/tests/output/nexus.out | 193 ++++++++---------- progenitor-macro/Cargo.toml | 6 +- progenitor-macro/src/lib.rs | 132 ++++++------- progenitor/Cargo.toml | 2 +- 13 files changed, 318 insertions(+), 342 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06c4eff24..db56f1b8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.45" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" +checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" [[package]] name = "autocfg" @@ -37,9 +37,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "bytes" @@ -109,9 +109,9 @@ checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" [[package]] name = "encoding_rs" -version = "0.8.29" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746" +checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" dependencies = [ "cfg-if", ] @@ -139,6 +139,7 @@ dependencies = [ "percent-encoding", "progenitor", "reqwest", + "schemars", "serde", "uuid", ] @@ -153,6 +154,15 @@ dependencies = [ "newline-converter", ] +[[package]] +name = "fastrand" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +dependencies = [ + "instant", +] + [[package]] name = "fnv" version = "1.0.7" @@ -284,9 +294,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if", "libc", @@ -295,9 +305,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.7" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" +checksum = "0c9de88456263e249e241fcd211d3954e2c9b0ef7ccfc235a444eb367cae3689" dependencies = [ "bytes", "fnv", @@ -329,13 +339,13 @@ dependencies = [ [[package]] name = "http" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes", "fnv", - "itoa", + "itoa 1.0.1", ] [[package]] @@ -357,15 +367,15 @@ checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" [[package]] name = "httpdate" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.15" +version = "0.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c" +checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" dependencies = [ "bytes", "futures-channel", @@ -376,7 +386,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa", + "itoa 0.4.8", "pin-project-lite", "socket2", "tokio", @@ -411,15 +421,24 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ "autocfg", "hashbrown", "serde", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "ipnet" version = "2.3.1" @@ -432,6 +451,12 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "js-sys" version = "0.3.55" @@ -449,9 +474,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.107" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "log" @@ -556,15 +581,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "openapiv3" -version = "1.0.0-beta.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45518fa48878a21efa793483d3c5a3dd5f8f98026fc3dade65104d8b78bb535" +checksum = "9de1b830d6f0f82e832f5a173d54f827f233e75b30f0f787c1289cca956879f8" dependencies = [ "indexmap", "serde", @@ -587,15 +612,15 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.71" +version = "0.9.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" dependencies = [ "autocfg", "cc", @@ -621,9 +646,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -633,21 +658,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.22" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" - -[[package]] -name = "ppv-lite86" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] @@ -708,59 +727,21 @@ dependencies = [ "proc-macro2", "progenitor-impl", "quote", + "serde", "serde_json", + "serde_tokenstream", "syn", ] [[package]] name = "quote" -version = "1.0.10" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "redox_syscall" version = "0.2.10" @@ -798,15 +779,16 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280" +checksum = "87f242f1488a539a79bac6dbe7c8609ae43b7914b7736210f239a37cccb32525" dependencies = [ "base64", "bytes", "encoding_rs", "futures-core", "futures-util", + "h2", "http", "http-body", "hyper", @@ -824,6 +806,7 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-native-tls", + "tokio-util", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -844,9 +827,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "same-file" @@ -869,9 +852,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271ac0c667b8229adf70f0f957697c96fafd7486ab7481e15dc5e45e3e6a4368" +checksum = "c6b5a3c80cea1ab61f4260238409510e814e38b4b563c06044edf91e7dc070e3" dependencies = [ "chrono", "dyn-clone", @@ -883,9 +866,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ebda811090b257411540779860bc09bf321bc587f58d2c5864309d1566214e7" +checksum = "41ae4dce13e8614c46ac3c38ef1c0d668b101df6ac39817aebdaa26642ddae9b" dependencies = [ "proc-macro2", "quote", @@ -936,18 +919,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.130" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", @@ -967,15 +950,26 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.70" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e277c495ac6cd1a01a58d0a0c574568b4d1ddf14f59965c6a58b8d96400b54f3" +checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" dependencies = [ - "itoa", + "itoa 1.0.1", "ryu", "serde", ] +[[package]] +name = "serde_tokenstream" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6deb15c3a535e81438110111d90168d91721652f502abb147f31cde129f683d" +dependencies = [ + "proc-macro2", + "serde", + "syn", +] + [[package]] name = "serde_urlencoded" version = "0.7.0" @@ -983,7 +977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" dependencies = [ "form_urlencoded", - "itoa", + "itoa 0.4.8", "ryu", "serde", ] @@ -1006,9 +1000,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.81" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" dependencies = [ "proc-macro2", "quote", @@ -1017,13 +1011,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if", + "fastrand", "libc", - "rand", "redox_syscall", "remove_dir_all", "winapi", @@ -1076,11 +1070,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" dependencies = [ - "autocfg", "bytes", "libc", "memchr", @@ -1161,7 +1154,7 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "typify" version = "0.0.6-dev" -source = "git+https://github.com/oxidecomputer/typify?branch=json-schema#0be9b35a5007e3f797e43ce41eba03dcee63e503" +source = "git+https://github.com/oxidecomputer/typify#a45d3058ec748c7040988700a003e4ef9aac6f02" dependencies = [ "typify-impl", "typify-macro", @@ -1170,7 +1163,7 @@ dependencies = [ [[package]] name = "typify-impl" version = "0.0.6-dev" -source = "git+https://github.com/oxidecomputer/typify?branch=json-schema#0be9b35a5007e3f797e43ce41eba03dcee63e503" +source = "git+https://github.com/oxidecomputer/typify#a45d3058ec748c7040988700a003e4ef9aac6f02" dependencies = [ "convert_case", "log", @@ -1186,12 +1179,14 @@ dependencies = [ [[package]] name = "typify-macro" version = "0.0.6-dev" -source = "git+https://github.com/oxidecomputer/typify?branch=json-schema#0be9b35a5007e3f797e43ce41eba03dcee63e503" +source = "git+https://github.com/oxidecomputer/typify#a45d3058ec748c7040988700a003e4ef9aac6f02" dependencies = [ "proc-macro2", "quote", "schemars", + "serde", "serde_json", + "serde_tokenstream", "syn", "typify-impl", ] diff --git a/Cargo.toml b/Cargo.toml index 6ce8c6a5c..f1d6fa788 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,16 @@ [workspace] members = [ + "example-build", + "example-macro", "progenitor", "progenitor-client", "progenitor-impl", "progenitor-macro", - "example-build", - "example-macro", ] default-members = [ + "example-build", + "example-macro", "progenitor", "progenitor-client", "progenitor-impl", diff --git a/example-build/Cargo.toml b/example-build/Cargo.toml index 07c06b591..86f4f41ad 100644 --- a/example-build/Cargo.toml +++ b/example-build/Cargo.toml @@ -6,11 +6,11 @@ edition = "2018" [dependencies] anyhow = "1.0" +chrono = { version = "0.4", features = ["serde"] } percent-encoding = "2.1" -serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.11", features = ["json", "stream"] } +serde = { version = "1.0", features = ["derive"] } uuid = { version = "0.8", features = ["serde", "v4"] } -chrono = { version = "0.4", features = ["serde"] } [build-dependencies] progenitor = { path = "../progenitor" } diff --git a/example-macro/Cargo.toml b/example-macro/Cargo.toml index 5a8df34c9..6eb4e7ef1 100644 --- a/example-macro/Cargo.toml +++ b/example-macro/Cargo.toml @@ -5,10 +5,11 @@ authors = ["Adam H. Leventhal "] edition = "2018" [dependencies] -progenitor = { path = "../progenitor" } anyhow = "1.0" +chrono = { version = "0.4", features = ["serde"] } percent-encoding = "2.1" -serde = { version = "1.0", features = ["derive"] } +progenitor = { path = "../progenitor" } reqwest = { version = "0.11", features = ["json", "stream"] } +schemars = "0.8" +serde = { version = "1.0", features = ["derive"] } uuid = { version = "0.8", features = ["serde", "v4"] } -chrono = { version = "0.4", features = ["serde"] } diff --git a/example-macro/src/main.rs b/example-macro/src/main.rs index 61e9b8459..2120a5141 100644 --- a/example-macro/src/main.rs +++ b/example-macro/src/main.rs @@ -1,16 +1,23 @@ -// Copyright 2021 Oxide Computer Company +// Copyright 2022 Oxide Computer Company use progenitor::generate_api; generate_api!( - "../sample_openapi/keeper.json", - (), - |_, request| { + spec = "../sample_openapi/keeper.json", + inner_type = (), + pre_hook = (|_, request| { println!("doing this {:?}", request); - }, - crate::all_done + }), + post_hook = crate::all_done, + derives = [schemars::JsonSchema], ); fn all_done(_: &(), _result: &reqwest::Result) {} +mod buildomat { + use progenitor::generate_api; + + generate_api!("../sample_openapi/buildomat.json"); +} + fn main() {} diff --git a/progenitor-impl/Cargo.toml b/progenitor-impl/Cargo.toml index 6ff6c2d43..a4d38b847 100644 --- a/progenitor-impl/Cargo.toml +++ b/progenitor-impl/Cargo.toml @@ -8,9 +8,10 @@ description = "An OpenAPI client generator - core implementation" [dependencies] anyhow = "1.0" +convert_case = "0.4" getopts = "0.2" indexmap = "1.7" -openapiv3 = "1.0.0-beta.5" +openapiv3 = "1.0.0" proc-macro2 = "1.0" quote = "1.0" regex = "1.5" @@ -18,9 +19,8 @@ rustfmt-wrapper = "0.1" schemars = { version = "0.8", features = [ "chrono", "uuid" ] } serde = { version = "1.0", features = [ "derive" ] } serde_json = "1.0" -convert_case = "0.4" -typify = { git = "https://github.com/oxidecomputer/typify", branch = "json-schema" } thiserror = "1.0" +typify = { git = "https://github.com/oxidecomputer/typify" } [dev-dependencies] expectorate = "1.0" diff --git a/progenitor-impl/src/lib.rs b/progenitor-impl/src/lib.rs index 85f88c3db..df688404a 100644 --- a/progenitor-impl/src/lib.rs +++ b/progenitor-impl/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2021 Oxide Computer Company +// Copyright 2022 Oxide Computer Company use std::{cmp::Ordering, collections::HashMap}; @@ -108,6 +108,11 @@ impl Generator { self } + pub fn with_derive(&mut self, derive: TokenStream) -> &mut Self { + self.type_space.add_derive(derive); + self + } + pub fn generate_tokens(&mut self, spec: &OpenAPI) -> Result { // Convert our components dictionary to schemars let schemas = spec @@ -194,7 +199,6 @@ impl Generator { } pub mod types { - use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #(#types)* } diff --git a/progenitor-impl/tests/output/buildomat.out b/progenitor-impl/tests/output/buildomat.out index 1b1305983..591fcc12d 100644 --- a/progenitor-impl/tests/output/buildomat.out +++ b/progenitor-impl/tests/output/buildomat.out @@ -19,9 +19,8 @@ mod progenitor_support { } pub mod types { - use schemars::JsonSchema; use serde::{Deserialize, Serialize}; - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Task { pub id: String, pub name: String, @@ -30,7 +29,7 @@ pub mod types { pub state: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TaskEvent { pub payload: String, pub seq: u32, @@ -38,14 +37,14 @@ pub mod types { pub time: chrono::DateTime, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TaskOutput { pub id: String, pub path: String, pub size: u64, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TaskSubmit { pub name: String, #[serde(default, skip_serializing_if = "Vec::is_empty")] @@ -53,35 +52,35 @@ pub mod types { pub script: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TaskSubmitResult { pub id: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct UploadedChunk { pub id: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct UserCreate { pub name: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct UserCreateResult { pub id: String, pub name: String, pub token: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WhoamiResult { pub id: String, pub name: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Worker { pub deleted: bool, pub id: String, @@ -93,58 +92,58 @@ pub mod types { pub tasks: Vec, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WorkerAddOutput { pub chunks: Vec, pub path: String, pub size: i64, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WorkerAppendTask { pub payload: String, pub stream: String, pub time: chrono::DateTime, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WorkerBootstrap { pub bootstrap: String, pub token: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WorkerBootstrapResult { pub id: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WorkerCompleteTask { pub failed: bool, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WorkerPingResult { pub poweroff: bool, #[serde(default, skip_serializing_if = "Option::is_none")] pub task: Option, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WorkerPingTask { pub id: String, pub output_rules: Vec, pub script: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WorkerTask { pub id: String, pub name: String, pub owner: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WorkersResult { pub workers: Vec, } diff --git a/progenitor-impl/tests/output/keeper.out b/progenitor-impl/tests/output/keeper.out index e38bbe5f7..fc9d17962 100644 --- a/progenitor-impl/tests/output/keeper.out +++ b/progenitor-impl/tests/output/keeper.out @@ -19,33 +19,32 @@ mod progenitor_support { } pub mod types { - use schemars::JsonSchema; use serde::{Deserialize, Serialize}; - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct EnrolBody { pub host: String, pub key: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GlobalJobsResult { pub summary: Vec, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OutputRecord { pub msg: String, pub stream: String, pub time: chrono::DateTime, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct PingResult { pub host: String, pub ok: bool, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ReportFinishBody { pub duration_millis: i32, pub end_time: chrono::DateTime, @@ -53,7 +52,7 @@ pub mod types { pub id: ReportId, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ReportId { pub host: String, pub job: String, @@ -62,25 +61,25 @@ pub mod types { pub uuid: String, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ReportOutputBody { pub id: ReportId, pub record: OutputRecord, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ReportResult { pub existed_already: bool, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ReportStartBody { pub id: ReportId, pub script: String, pub start_time: chrono::DateTime, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ReportSummary { pub age_seconds: i32, pub duration_seconds: i32, diff --git a/progenitor-impl/tests/output/nexus.out b/progenitor-impl/tests/output/nexus.out index dcb635bd3..bd4ca7438 100644 --- a/progenitor-impl/tests/output/nexus.out +++ b/progenitor-impl/tests/output/nexus.out @@ -19,10 +19,9 @@ mod progenitor_support { } pub mod types { - use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #[doc = "A count of bytes, typically used either for memory or storage capacity\n\nThe maximum supported byte count is [`i64::MAX`]. This makes it somewhat inconvenient to define constructors: a u32 constructor can be infallible, but an i64 constructor can fail (if the value is negative) and a u64 constructor can fail (if the value is larger than i64::MAX). We provide all of these for consumers' convenience."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ByteCount(pub u64); impl std::ops::Deref for ByteCount { type Target = u64; @@ -32,9 +31,7 @@ pub mod types { } #[doc = "The type of an individual datum of a metric."] - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum DatumType { Bool, I64, @@ -64,7 +61,7 @@ pub mod types { } #[doc = "Client view of an [`Disk`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Disk { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -92,7 +89,7 @@ pub mod types { } #[doc = "Create-time parameters for a [`Disk`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct DiskCreate { pub description: String, pub name: Name, @@ -107,13 +104,13 @@ pub mod types { } #[doc = "Parameters for the [`Disk`] to be attached or detached to an instance"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct DiskIdentifier { pub disk: Name, } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct DiskResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -122,7 +119,7 @@ pub mod types { pub next_page: Option, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "state", content = "instance")] pub enum DiskState { #[serde(rename = "creating")] @@ -142,7 +139,7 @@ pub mod types { } #[doc = "The name and type information for a field of a timeseries schema."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct FieldSchema { pub name: String, pub source: FieldSource, @@ -150,9 +147,7 @@ pub mod types { } #[doc = "The source from which a field is derived, the target or metric."] - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum FieldSource { Target, Metric, @@ -168,9 +163,7 @@ pub mod types { } #[doc = "The `FieldType` identifies the data type of a target or metric field."] - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum FieldType { String, I64, @@ -192,9 +185,7 @@ pub mod types { } #[doc = "Supported set of sort modes for scanning by id only.\n\nCurrently, we only support scanning in ascending order."] - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum IdSortMode { #[serde(rename = "id-ascending")] IdAscending, @@ -209,7 +200,7 @@ pub mod types { } #[doc = "Identity-related metadata that's included in nearly all public API objects"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct IdentityMetadata { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -225,7 +216,7 @@ pub mod types { } #[doc = "Client view of an [`Instance`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Instance { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -252,7 +243,7 @@ pub mod types { } #[doc = "The number of CPUs in an Instance"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct InstanceCpuCount(pub u16); impl std::ops::Deref for InstanceCpuCount { type Target = u16; @@ -262,7 +253,7 @@ pub mod types { } #[doc = "Create-time parameters for an [`Instance`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct InstanceCreate { pub description: String, pub hostname: String, @@ -272,7 +263,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct InstanceResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -282,9 +273,7 @@ pub mod types { } #[doc = "Running state of an Instance (primarily: booted or stopped)\n\nThis typically reflects whether it's starting, running, stopping, or stopped, but also includes states related to the Instance's lifecycle"] - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum InstanceState { #[serde(rename = "creating")] Creating, @@ -323,7 +312,7 @@ pub mod types { } #[doc = "An IPv4 subnet, including prefix and subnet mask"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Ipv4Net(pub String); impl std::ops::Deref for Ipv4Net { type Target = String; @@ -333,7 +322,7 @@ pub mod types { } #[doc = "An IPv6 subnet, including prefix and subnet mask"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Ipv6Net(pub String); impl std::ops::Deref for Ipv6Net { type Target = String; @@ -343,7 +332,7 @@ pub mod types { } #[doc = "An inclusive-inclusive range of IP ports. The second port may be omitted to represent a single port"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct L4PortRange(pub String); impl std::ops::Deref for L4PortRange { type Target = String; @@ -352,13 +341,13 @@ pub mod types { } } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct LoginParams { pub username: String, } #[doc = "A Media Access Control address, in EUI-48 format"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct MacAddr(pub String); impl std::ops::Deref for MacAddr { type Target = String; @@ -368,7 +357,7 @@ pub mod types { } #[doc = "Names must begin with a lower case ASCII letter, be composed exclusively of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end with a '-'."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Name(pub String); impl std::ops::Deref for Name { type Target = String; @@ -378,9 +367,7 @@ pub mod types { } #[doc = "Supported set of sort modes for scanning by name or id"] - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum NameOrIdSortMode { #[serde(rename = "name-ascending")] NameAscending, @@ -401,9 +388,7 @@ pub mod types { } #[doc = "Supported set of sort modes for scanning by name only\n\nCurrently, we only support scanning in ascending order."] - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum NameSortMode { #[serde(rename = "name-ascending")] NameAscending, @@ -418,7 +403,7 @@ pub mod types { } #[doc = "A `NetworkInterface` represents a virtual network interface device."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct NetworkInterface { pub identity: IdentityMetadata, #[doc = "The Instance to which the interface belongs."] @@ -433,7 +418,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct NetworkInterfaceResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -443,7 +428,7 @@ pub mod types { } #[doc = "Client view of an [`Organization`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Organization { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -459,14 +444,14 @@ pub mod types { } #[doc = "Create-time parameters for an [`Organization`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationCreate { pub description: String, pub name: Name, } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -476,7 +461,7 @@ pub mod types { } #[doc = "Updateable properties of an [`Organization`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct OrganizationUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -485,7 +470,7 @@ pub mod types { } #[doc = "Client view of a [`Project`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Project { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -503,14 +488,14 @@ pub mod types { } #[doc = "Create-time parameters for a [`Project`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ProjectCreate { pub description: String, pub name: Name, } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ProjectResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -520,7 +505,7 @@ pub mod types { } #[doc = "Updateable properties of a [`Project`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ProjectUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -529,13 +514,13 @@ pub mod types { } #[doc = "Client view of an [`Rack`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Rack { pub identity: IdentityMetadata, } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RackResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -545,14 +530,14 @@ pub mod types { } #[doc = "Client view of a [`Role`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Role { pub description: String, pub name: RoleName, } #[doc = "Role names consist of two string components separated by dot (\".\")."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RoleName(pub String); impl std::ops::Deref for RoleName { type Target = String; @@ -562,7 +547,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RoleResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -571,7 +556,7 @@ pub mod types { pub next_page: Option, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "type", content = "value")] pub enum RouteDestination { #[serde(rename = "ip")] @@ -582,7 +567,7 @@ pub mod types { Subnet(Name), } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "type", content = "value")] pub enum RouteTarget { #[serde(rename = "ip")] @@ -598,7 +583,7 @@ pub mod types { } #[doc = "A route defines a rule that governs where traffic should be sent based on its destination."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RouterRoute { pub destination: RouteDestination, pub identity: IdentityMetadata, @@ -609,7 +594,7 @@ pub mod types { } #[doc = "Create-time parameters for a [`RouterRoute`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RouterRouteCreateParams { pub description: String, pub destination: RouteDestination, @@ -618,9 +603,7 @@ pub mod types { } #[doc = "The classification of a [`RouterRoute`] as defined by the system. The kind determines certain attributes such as if the route is modifiable and describes how or where the route was created.\n\nSee [RFD-21](https://rfd.shared.oxide.computer/rfd/0021#concept-router) for more context"] - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum RouterRouteKind { Default, VpcSubnet, @@ -640,7 +623,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RouterRouteResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -650,7 +633,7 @@ pub mod types { } #[doc = "Updateable properties of a [`RouterRoute`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RouterRouteUpdateParams { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -660,13 +643,13 @@ pub mod types { pub target: RouteTarget, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Saga { pub id: uuid::Uuid, pub state: SagaState, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "error")] pub enum SagaErrorInfo { #[serde(rename = "actionFailed")] @@ -682,7 +665,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct SagaResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -691,7 +674,7 @@ pub mod types { pub next_page: Option, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "state")] pub enum SagaState { #[serde(rename = "running")] @@ -706,7 +689,7 @@ pub mod types { } #[doc = "Client view of an [`Sled`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Sled { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -724,7 +707,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct SledResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -734,7 +717,7 @@ pub mod types { } #[doc = "Names are constructed by concatenating the target and metric names with ':'. Target and metric names must be lowercase alphanumeric characters with '_' separating words."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TimeseriesName(pub String); impl std::ops::Deref for TimeseriesName { type Target = String; @@ -744,7 +727,7 @@ pub mod types { } #[doc = "The schema for a timeseries.\n\nThis includes the name of the timeseries, as well as the datum type of its metric and the schema for each field."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TimeseriesSchema { pub created: chrono::DateTime, pub datum_type: DatumType, @@ -753,7 +736,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TimeseriesSchemaResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -763,7 +746,7 @@ pub mod types { } #[doc = "Client view of a [`User`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct User { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -779,7 +762,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct UserResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -789,7 +772,7 @@ pub mod types { } #[doc = "Client view of a [`Vpc`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Vpc { #[doc = "human-readable free-form text about a resource"] pub description: String, @@ -813,7 +796,7 @@ pub mod types { } #[doc = "Create-time parameters for a [`Vpc`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcCreate { pub description: String, #[serde(rename = "dnsName")] @@ -822,7 +805,7 @@ pub mod types { } #[doc = "A single rule in a VPC firewall"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcFirewallRule { pub action: VpcFirewallRuleAction, pub direction: VpcFirewallRuleDirection, @@ -835,9 +818,7 @@ pub mod types { pub targets: Vec, } - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum VpcFirewallRuleAction { #[serde(rename = "allow")] Allow, @@ -854,9 +835,7 @@ pub mod types { } } - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum VpcFirewallRuleDirection { #[serde(rename = "inbound")] Inbound, @@ -874,7 +853,7 @@ pub mod types { } #[doc = "Filter for a firewall rule. A given packet must match every field that is present for the rule to apply to it. A packet matches a field if any entry in that field matches the packet."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcFirewallRuleFilter { #[doc = "If present, the sources (if incoming) or destinations (if outgoing) this rule applies to."] #[serde(default, skip_serializing_if = "Option::is_none")] @@ -887,7 +866,7 @@ pub mod types { pub protocols: Option>, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "type", content = "value")] pub enum VpcFirewallRuleHostFilter { #[serde(rename = "vpc")] @@ -903,9 +882,7 @@ pub mod types { } #[doc = "The protocols that may be specified in a firewall rule's filter"] - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum VpcFirewallRuleProtocol { #[serde(rename = "TCP")] Tcp, @@ -926,7 +903,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcFirewallRuleResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -935,9 +912,7 @@ pub mod types { pub next_page: Option, } - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum VpcFirewallRuleStatus { #[serde(rename = "disabled")] Disabled, @@ -954,7 +929,7 @@ pub mod types { } } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "type", content = "value")] pub enum VpcFirewallRuleTarget { #[serde(rename = "vpc")] @@ -966,7 +941,7 @@ pub mod types { } #[doc = "A single rule in a VPC firewall"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcFirewallRuleUpdate { pub action: VpcFirewallRuleAction, #[doc = "human-readable free-form text about a resource"] @@ -980,7 +955,7 @@ pub mod types { pub targets: Vec, } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcFirewallRuleUpdateParams( pub std::collections::HashMap, ); @@ -991,7 +966,7 @@ pub mod types { } } - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcFirewallRuleUpdateResult(pub std::collections::HashMap); impl std::ops::Deref for VpcFirewallRuleUpdateResult { type Target = std::collections::HashMap; @@ -1001,7 +976,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -1011,7 +986,7 @@ pub mod types { } #[doc = "A VPC router defines a series of rules that indicate where traffic should be sent depending on its destination."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcRouter { pub identity: IdentityMetadata, pub kind: VpcRouterKind, @@ -1020,15 +995,13 @@ pub mod types { } #[doc = "Create-time parameters for a [`VpcRouter`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcRouterCreate { pub description: String, pub name: Name, } - #[derive( - Serialize, Deserialize, JsonSchema, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, - )] + #[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum VpcRouterKind { #[serde(rename = "system")] System, @@ -1046,7 +1019,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcRouterResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -1056,7 +1029,7 @@ pub mod types { } #[doc = "Updateable properties of a [`VpcRouter`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcRouterUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -1065,7 +1038,7 @@ pub mod types { } #[doc = "A VPC subnet represents a logical grouping for instances that allows network traffic between them, within a IPv4 subnetwork or optionall an IPv6 subnetwork."] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcSubnet { pub identity: IdentityMetadata, #[serde( @@ -1085,7 +1058,7 @@ pub mod types { } #[doc = "Create-time parameters for a [`VpcSubnet`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcSubnetCreate { pub description: String, #[serde(rename = "ipv4Block", default, skip_serializing_if = "Option::is_none")] @@ -1096,7 +1069,7 @@ pub mod types { } #[doc = "A single page of results"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcSubnetResultsPage { #[doc = "list of items on this page of results"] pub items: Vec, @@ -1106,7 +1079,7 @@ pub mod types { } #[doc = "Updateable properties of a [`VpcSubnet`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcSubnetUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, @@ -1119,7 +1092,7 @@ pub mod types { } #[doc = "Updateable properties of a [`Vpc`]"] - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VpcUpdate { #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, diff --git a/progenitor-macro/Cargo.toml b/progenitor-macro/Cargo.toml index 8141a9056..761db32c1 100644 --- a/progenitor-macro/Cargo.toml +++ b/progenitor-macro/Cargo.toml @@ -7,11 +7,13 @@ repository = "https://github.com/oxidecomputer/progenitor.git" description = "An OpenAPI client generator - macros" [dependencies] -openapiv3 = "1.0.0-beta.5" +openapiv3 = "1.0.0" +proc-macro2 = "1.0" progenitor-impl = { path = "../progenitor-impl" } quote = "1.0" -proc-macro2 = "1.0" +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +serde_tokenstream = "0.1.3" syn = "1.0" [lib] diff --git a/progenitor-macro/src/lib.rs b/progenitor-macro/src/lib.rs index c8ae7934b..099308ad9 100644 --- a/progenitor-macro/src/lib.rs +++ b/progenitor-macro/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2021 Oxide Computer Company +// Copyright 2022 Oxide Computer Company use std::path::Path; @@ -6,10 +6,9 @@ use openapiv3::OpenAPI; use proc_macro::TokenStream; use progenitor_impl::Generator; use quote::{quote, ToTokens}; -use syn::{ - parse::{Parse, ParseStream}, - ExprClosure, LitStr, Token, -}; +use serde::Deserialize; +use serde_tokenstream::ParseWrapper; +use syn::LitStr; #[proc_macro] pub fn generate_api(item: TokenStream) -> TokenStream { @@ -19,101 +18,96 @@ pub fn generate_api(item: TokenStream) -> TokenStream { } } +#[derive(Deserialize)] struct Settings { - file: LitStr, - inner: Option, - pre: Option, - post: Option, + spec: ParseWrapper, + inner_type: Option>, + pre_hook: Option>, + post_hook: Option>, + #[serde(default)] + derives: Vec>, } -impl Parse for Settings { - fn parse(input: ParseStream) -> Result { - let file = input.parse::()?; - let inner = parse_inner(input)?; - let pre = parse_hook(input)?; - let post = parse_hook(input)?; +#[derive(Debug)] +struct ClosureOrPath(proc_macro2::TokenStream); - // Optional trailing comma. - if input.peek(Token!(,)) { - let _ = input.parse::(); - } +impl syn::parse::Parse for ClosureOrPath { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let lookahead = input.lookahead1(); - Ok(Settings { - file, - inner, - pre, - post, - }) - } -} + if lookahead.peek(syn::token::Paren) { + let group: proc_macro2::Group = input.parse()?; + return syn::parse2::(group.stream()); + } -fn parse_inner( - input: ParseStream, -) -> Result, syn::Error> { - if input.is_empty() { - return Ok(None); - } - let _: Token!(,) = input.parse()?; - if input.is_empty() { - return Ok(None); - } - Ok(Some(input.parse::()?.to_token_stream())) -} + if let Ok(closure) = input.parse::() { + return Ok(Self(closure.to_token_stream())); + } -fn parse_hook( - input: ParseStream, -) -> Result, syn::Error> { - if input.is_empty() { - return Ok(None); - } - let _: Token!(,) = input.parse()?; - if input.is_empty() { - return Ok(None); - } - if let Ok(closure) = input.parse::() { - Ok(Some(closure.to_token_stream())) - } else { - Ok(Some(input.parse::()?.to_token_stream())) + input + .parse::() + .map(|path| Self(path.to_token_stream())) } } fn do_generate_api(item: TokenStream) -> Result { - let Settings { - file, - inner, - pre, - post, - } = syn::parse::(item)?; + let (spec, inner_type, pre_hook, post_hook, derives) = + if let Ok(spec) = syn::parse::(item.clone()) { + (spec, None, None, None, Vec::new()) + } else { + let Settings { + spec, + inner_type, + pre_hook, + post_hook, + derives, + } = serde_tokenstream::from_tokenstream(&item.into())?; + ( + spec.into_inner(), + inner_type.map(|x| x.into_inner()), + pre_hook.map(|x| x.into_inner()), + post_hook.map(|x| x.into_inner()), + derives.into_iter().map(ParseWrapper::into_inner).collect(), + ) + }; + let dir = std::env::var("CARGO_MANIFEST_DIR").map_or_else( |_| std::env::current_dir().unwrap(), |s| Path::new(&s).to_path_buf(), ); - let path = dir.join(file.value()); + let path = dir.join(spec.value()); let path_str = path.to_string_lossy(); - let spec: OpenAPI = + let oapi: OpenAPI = serde_json::from_reader(std::fs::File::open(&path).map_err(|e| { syn::Error::new( - file.span(), + spec.span(), format!("couldn't read file {}: {}", path_str, e.to_string()), ) })?) .map_err(|e| { syn::Error::new( - file.span(), + spec.span(), format!("failed to parse {}: {}", path_str, e.to_string()), ) })?; let mut builder = Generator::new(); - inner.map(|inner_type| builder.with_inner_type(inner_type)); - pre.map(|pre_hook| builder.with_pre_hook(pre_hook)); - post.map(|post_hook| builder.with_post_hook(post_hook)); - let code = builder.generate_tokens(&spec).map_err(|e| { + inner_type.map(|inner_type| { + builder.with_inner_type(inner_type.to_token_stream()) + }); + pre_hook.map(|pre_hook| builder.with_pre_hook(pre_hook.0)); + post_hook.map(|post_hook| builder.with_post_hook(post_hook.0)); + + derives.into_iter().for_each(|derive| { + builder.with_derive(derive.to_token_stream()); + }); + + let code = builder.generate_tokens(&oapi).map_err(|e| { syn::Error::new( - file.span(), - format!("generation error for {}: {}", file.value(), e.to_string()), + spec.span(), + format!("generation error for {}: {}", spec.value(), e.to_string()), ) })?; diff --git a/progenitor/Cargo.toml b/progenitor/Cargo.toml index 83437a12b..97e55fc7a 100644 --- a/progenitor/Cargo.toml +++ b/progenitor/Cargo.toml @@ -11,7 +11,7 @@ progenitor-macro = { path = "../progenitor-macro" } progenitor-impl = { path = "../progenitor-impl" } anyhow = "1.0" getopts = "0.2" -openapiv3 = "1.0.0-beta.5" +openapiv3 = "1.0.0" serde = { version = "1.0", features = [ "derive" ] } serde_json = "1.0"