allow for type adjustments: renames, and additional derives (#234)

This commit is contained in:
Adam Leventhal 2022-11-14 10:51:05 -08:00 committed by GitHub
parent 522446d9b8
commit 68290b08e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 20 deletions

19
Cargo.lock generated
View File

@ -1438,9 +1438,9 @@ dependencies = [
[[package]]
name = "serde_tokenstream"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd80de2b23fd8f323001816f6db55b64b87302043519a45548708620ae6c71ef"
checksum = "2794f0ba0179a8ca422c30d9975d86faf8306be0164bfc3b0b1ca4f060ac639d"
dependencies = [
"proc-macro2",
"serde",
@ -1849,9 +1849,8 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "typify"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e8486352f3c946e69f983558cfc09b295250b01e01b381ec67a05a812d01d63"
version = "0.0.11-dev"
source = "git+https://github.com/oxidecomputer/typify#6f20ad934a8da5aa3a94d25d2ab3cca1e60f53d9"
dependencies = [
"typify-impl",
"typify-macro",
@ -1859,9 +1858,8 @@ dependencies = [
[[package]]
name = "typify-impl"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7624d0b911df6e2bbf34a236f76281f93b294cdde1d4df1dbdb748e5a7fefa5"
version = "0.0.11-dev"
source = "git+https://github.com/oxidecomputer/typify#6f20ad934a8da5aa3a94d25d2ab3cca1e60f53d9"
dependencies = [
"heck",
"log",
@ -1878,9 +1876,8 @@ dependencies = [
[[package]]
name = "typify-macro"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c42802aa033cee7650a4e1509ba7d5848a56f84be7c4b31e4385ee12445e942"
version = "0.0.11-dev"
source = "git+https://github.com/oxidecomputer/typify#6f20ad934a8da5aa3a94d25d2ab3cca1e60f53d9"
dependencies = [
"proc-macro2",
"quote",

View File

@ -21,8 +21,8 @@ serde_json = "1.0"
syn = { version = "1.0", features = ["parsing"] }
thiserror = "1.0"
# To publish, use a numbered version
typify = "0.0.10"
#typify = { git = "https://github.com/oxidecomputer/typify" }
#typify = "0.0.10"
typify = { git = "https://github.com/oxidecomputer/typify" }
unicode-ident = "1.0.5"
[dev-dependencies]

View File

@ -1,6 +1,6 @@
// Copyright 2022 Oxide Computer Company
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};
use openapiv3::OpenAPI;
use proc_macro2::TokenStream;
@ -11,6 +11,8 @@ use typify::{TypeSpace, TypeSpaceSettings};
use crate::to_schema::ToSchema;
pub use typify::TypeSpacePatch as TypePatch;
mod method;
mod template;
mod to_schema;
@ -49,6 +51,7 @@ pub struct GenerationSettings {
pre_hook: Option<TokenStream>,
post_hook: Option<TokenStream>,
extra_derives: Vec<String>,
patch: HashMap<String, TypePatch>,
}
#[derive(Clone, Deserialize, PartialEq, Eq)]
@ -109,6 +112,16 @@ impl GenerationSettings {
self.extra_derives.push(derive.to_string());
self
}
pub fn with_patch<S: AsRef<str>>(
&mut self,
type_name: S,
patch: &TypePatch,
) -> &mut Self {
self.patch
.insert(type_name.as_ref().to_string(), patch.clone());
self
}
}
impl Default for Generator {
@ -133,6 +146,9 @@ impl Generator {
settings.extra_derives.iter().for_each(|derive| {
let _ = type_settings.with_derive(derive.clone());
});
settings.patch.iter().for_each(|(type_name, patch)| {
type_settings.with_patch(type_name, patch);
});
Self {
type_space: TypeSpace::new(&type_settings),
settings: settings.clone(),

View File

@ -1724,7 +1724,7 @@ pub mod types {
///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 '-'. Names cannot be a UUID though they may contain a UUID.
#[derive(Clone, Debug, Serialize, JsonSchema)]
#[derive(Clone, Debug, Serialize, Hash, JsonSchema)]
pub struct Name(String);
impl std::ops::Deref for Name {
type Target = String;

View File

@ -3,7 +3,7 @@
use std::{fs::File, path::PathBuf};
use progenitor_impl::{
GenerationSettings, Generator, InterfaceStyle, TagStyle,
GenerationSettings, Generator, InterfaceStyle, TagStyle, TypePatch,
};
#[track_caller]
@ -25,7 +25,8 @@ fn verify_apis(openapi_file: &str) {
GenerationSettings::default()
.with_interface(InterfaceStyle::Builder)
.with_tag(TagStyle::Merged)
.with_derive("JsonSchema"),
.with_derive("JsonSchema")
.with_patch("Name", TypePatch::default().with_derive("Hash")),
);
let output = generator.generate_text_normalize_comments(&spec).unwrap();
expectorate::assert_contents(

View File

@ -1,11 +1,11 @@
// Copyright 2022 Oxide Computer Company
use std::path::Path;
use std::{collections::HashMap, path::Path};
use openapiv3::OpenAPI;
use proc_macro::TokenStream;
use progenitor_impl::{
GenerationSettings, Generator, InterfaceStyle, TagStyle,
GenerationSettings, Generator, InterfaceStyle, TagStyle, TypePatch,
};
use quote::{quote, ToTokens};
use serde::Deserialize;
@ -80,6 +80,29 @@ struct MacroSettings {
post_hook: Option<ParseWrapper<ClosureOrPath>>,
#[serde(default)]
derives: Vec<ParseWrapper<syn::Path>>,
#[serde(default)]
patch: HashMap<ParseWrapper<syn::Type>, MacroPatch>,
}
#[derive(Deserialize)]
struct MacroPatch {
#[serde(default)]
rename: Option<String>,
#[serde(default)]
derives: Vec<ParseWrapper<syn::Path>>,
}
impl From<MacroPatch> for TypePatch {
fn from(a: MacroPatch) -> Self {
let mut s = Self::default();
a.rename.iter().for_each(|rename| {
s.with_rename(rename);
});
a.derives.iter().for_each(|derive| {
s.with_derive(derive.to_token_stream().to_string());
});
s
}
}
#[derive(Deserialize)]
@ -129,6 +152,7 @@ fn do_generate_api(item: TokenStream) -> Result<TokenStream, syn::Error> {
pre_hook,
post_hook,
derives,
patch,
} = serde_tokenstream::from_tokenstream(&item.into())?;
let mut settings = GenerationSettings::default();
settings.with_interface(interface);
@ -144,6 +168,12 @@ fn do_generate_api(item: TokenStream) -> Result<TokenStream, syn::Error> {
derives.into_iter().for_each(|derive| {
settings.with_derive(derive.to_token_stream());
});
patch.into_iter().for_each(|(type_name, patch)| {
settings.with_patch(
type_name.to_token_stream().to_string(),
&patch.into(),
);
});
(spec.into_inner(), settings)
};

View File

@ -16,4 +16,5 @@ pub use progenitor_impl::GenerationSettings;
pub use progenitor_impl::Generator;
pub use progenitor_impl::InterfaceStyle;
pub use progenitor_impl::TagStyle;
pub use progenitor_impl::TypePatch;
pub use progenitor_macro::generate_api;

View File

@ -1,4 +1,4 @@
// Copyright 2021 Oxide Computer Company
// Copyright 2022 Oxide Computer Company
mod positional {
use futures::StreamExt;
@ -31,6 +31,11 @@ mod builder_untagged {
spec = "../sample_openapi/nexus.json",
interface = Builder,
tags = Merged,
patch = {
Name = {
derives = [Hash],
}
}
);
}