allow for type adjustments: renames, and additional derives (#234)
This commit is contained in:
parent
522446d9b8
commit
68290b08e0
|
@ -1438,9 +1438,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_tokenstream"
|
name = "serde_tokenstream"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd80de2b23fd8f323001816f6db55b64b87302043519a45548708620ae6c71ef"
|
checksum = "2794f0ba0179a8ca422c30d9975d86faf8306be0164bfc3b0b1ca4f060ac639d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1849,9 +1849,8 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typify"
|
name = "typify"
|
||||||
version = "0.0.10"
|
version = "0.0.11-dev"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/oxidecomputer/typify#6f20ad934a8da5aa3a94d25d2ab3cca1e60f53d9"
|
||||||
checksum = "2e8486352f3c946e69f983558cfc09b295250b01e01b381ec67a05a812d01d63"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typify-impl",
|
"typify-impl",
|
||||||
"typify-macro",
|
"typify-macro",
|
||||||
|
@ -1859,9 +1858,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typify-impl"
|
name = "typify-impl"
|
||||||
version = "0.0.10"
|
version = "0.0.11-dev"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/oxidecomputer/typify#6f20ad934a8da5aa3a94d25d2ab3cca1e60f53d9"
|
||||||
checksum = "a7624d0b911df6e2bbf34a236f76281f93b294cdde1d4df1dbdb748e5a7fefa5"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1878,9 +1876,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typify-macro"
|
name = "typify-macro"
|
||||||
version = "0.0.10"
|
version = "0.0.11-dev"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/oxidecomputer/typify#6f20ad934a8da5aa3a94d25d2ab3cca1e60f53d9"
|
||||||
checksum = "0c42802aa033cee7650a4e1509ba7d5848a56f84be7c4b31e4385ee12445e942"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -21,8 +21,8 @@ serde_json = "1.0"
|
||||||
syn = { version = "1.0", features = ["parsing"] }
|
syn = { version = "1.0", features = ["parsing"] }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
# To publish, use a numbered version
|
# To publish, use a numbered version
|
||||||
typify = "0.0.10"
|
#typify = "0.0.10"
|
||||||
#typify = { git = "https://github.com/oxidecomputer/typify" }
|
typify = { git = "https://github.com/oxidecomputer/typify" }
|
||||||
unicode-ident = "1.0.5"
|
unicode-ident = "1.0.5"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright 2022 Oxide Computer Company
|
// Copyright 2022 Oxide Computer Company
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use openapiv3::OpenAPI;
|
use openapiv3::OpenAPI;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
|
@ -11,6 +11,8 @@ use typify::{TypeSpace, TypeSpaceSettings};
|
||||||
|
|
||||||
use crate::to_schema::ToSchema;
|
use crate::to_schema::ToSchema;
|
||||||
|
|
||||||
|
pub use typify::TypeSpacePatch as TypePatch;
|
||||||
|
|
||||||
mod method;
|
mod method;
|
||||||
mod template;
|
mod template;
|
||||||
mod to_schema;
|
mod to_schema;
|
||||||
|
@ -49,6 +51,7 @@ pub struct GenerationSettings {
|
||||||
pre_hook: Option<TokenStream>,
|
pre_hook: Option<TokenStream>,
|
||||||
post_hook: Option<TokenStream>,
|
post_hook: Option<TokenStream>,
|
||||||
extra_derives: Vec<String>,
|
extra_derives: Vec<String>,
|
||||||
|
patch: HashMap<String, TypePatch>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, PartialEq, Eq)]
|
#[derive(Clone, Deserialize, PartialEq, Eq)]
|
||||||
|
@ -109,6 +112,16 @@ impl GenerationSettings {
|
||||||
self.extra_derives.push(derive.to_string());
|
self.extra_derives.push(derive.to_string());
|
||||||
self
|
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 {
|
impl Default for Generator {
|
||||||
|
@ -133,6 +146,9 @@ impl Generator {
|
||||||
settings.extra_derives.iter().for_each(|derive| {
|
settings.extra_derives.iter().for_each(|derive| {
|
||||||
let _ = type_settings.with_derive(derive.clone());
|
let _ = type_settings.with_derive(derive.clone());
|
||||||
});
|
});
|
||||||
|
settings.patch.iter().for_each(|(type_name, patch)| {
|
||||||
|
type_settings.with_patch(type_name, patch);
|
||||||
|
});
|
||||||
Self {
|
Self {
|
||||||
type_space: TypeSpace::new(&type_settings),
|
type_space: TypeSpace::new(&type_settings),
|
||||||
settings: settings.clone(),
|
settings: settings.clone(),
|
||||||
|
|
|
@ -1724,7 +1724,7 @@ pub mod types {
|
||||||
///Names must begin with a lower case ASCII letter, be composed exclusively
|
///Names must begin with a lower case ASCII letter, be composed exclusively
|
||||||
/// of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end
|
/// of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end
|
||||||
/// with a '-'. Names cannot be a UUID though they may contain a UUID.
|
/// 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);
|
pub struct Name(String);
|
||||||
impl std::ops::Deref for Name {
|
impl std::ops::Deref for Name {
|
||||||
type Target = String;
|
type Target = String;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use std::{fs::File, path::PathBuf};
|
use std::{fs::File, path::PathBuf};
|
||||||
|
|
||||||
use progenitor_impl::{
|
use progenitor_impl::{
|
||||||
GenerationSettings, Generator, InterfaceStyle, TagStyle,
|
GenerationSettings, Generator, InterfaceStyle, TagStyle, TypePatch,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
@ -25,7 +25,8 @@ fn verify_apis(openapi_file: &str) {
|
||||||
GenerationSettings::default()
|
GenerationSettings::default()
|
||||||
.with_interface(InterfaceStyle::Builder)
|
.with_interface(InterfaceStyle::Builder)
|
||||||
.with_tag(TagStyle::Merged)
|
.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();
|
let output = generator.generate_text_normalize_comments(&spec).unwrap();
|
||||||
expectorate::assert_contents(
|
expectorate::assert_contents(
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// Copyright 2022 Oxide Computer Company
|
// Copyright 2022 Oxide Computer Company
|
||||||
|
|
||||||
use std::path::Path;
|
use std::{collections::HashMap, path::Path};
|
||||||
|
|
||||||
use openapiv3::OpenAPI;
|
use openapiv3::OpenAPI;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use progenitor_impl::{
|
use progenitor_impl::{
|
||||||
GenerationSettings, Generator, InterfaceStyle, TagStyle,
|
GenerationSettings, Generator, InterfaceStyle, TagStyle, TypePatch,
|
||||||
};
|
};
|
||||||
use quote::{quote, ToTokens};
|
use quote::{quote, ToTokens};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -80,6 +80,29 @@ struct MacroSettings {
|
||||||
post_hook: Option<ParseWrapper<ClosureOrPath>>,
|
post_hook: Option<ParseWrapper<ClosureOrPath>>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
derives: Vec<ParseWrapper<syn::Path>>,
|
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)]
|
#[derive(Deserialize)]
|
||||||
|
@ -129,6 +152,7 @@ fn do_generate_api(item: TokenStream) -> Result<TokenStream, syn::Error> {
|
||||||
pre_hook,
|
pre_hook,
|
||||||
post_hook,
|
post_hook,
|
||||||
derives,
|
derives,
|
||||||
|
patch,
|
||||||
} = serde_tokenstream::from_tokenstream(&item.into())?;
|
} = serde_tokenstream::from_tokenstream(&item.into())?;
|
||||||
let mut settings = GenerationSettings::default();
|
let mut settings = GenerationSettings::default();
|
||||||
settings.with_interface(interface);
|
settings.with_interface(interface);
|
||||||
|
@ -144,6 +168,12 @@ fn do_generate_api(item: TokenStream) -> Result<TokenStream, syn::Error> {
|
||||||
derives.into_iter().for_each(|derive| {
|
derives.into_iter().for_each(|derive| {
|
||||||
settings.with_derive(derive.to_token_stream());
|
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)
|
(spec.into_inner(), settings)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,4 +16,5 @@ pub use progenitor_impl::GenerationSettings;
|
||||||
pub use progenitor_impl::Generator;
|
pub use progenitor_impl::Generator;
|
||||||
pub use progenitor_impl::InterfaceStyle;
|
pub use progenitor_impl::InterfaceStyle;
|
||||||
pub use progenitor_impl::TagStyle;
|
pub use progenitor_impl::TagStyle;
|
||||||
|
pub use progenitor_impl::TypePatch;
|
||||||
pub use progenitor_macro::generate_api;
|
pub use progenitor_macro::generate_api;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Oxide Computer Company
|
// Copyright 2022 Oxide Computer Company
|
||||||
|
|
||||||
mod positional {
|
mod positional {
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
@ -31,6 +31,11 @@ mod builder_untagged {
|
||||||
spec = "../sample_openapi/nexus.json",
|
spec = "../sample_openapi/nexus.json",
|
||||||
interface = Builder,
|
interface = Builder,
|
||||||
tags = Merged,
|
tags = Merged,
|
||||||
|
patch = {
|
||||||
|
Name = {
|
||||||
|
derives = [Hash],
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue