Skip to content

Commit

Permalink
Merge pull request #435 from kazk/refactor-derive-with-darling
Browse files Browse the repository at this point in the history
Refactor kube-derive using darling
  • Loading branch information
clux committed Feb 24, 2021
2 parents 6b9ce1f + 21d6754 commit c7e0b97
Show file tree
Hide file tree
Showing 10 changed files with 386 additions and 472 deletions.
2 changes: 2 additions & 0 deletions kube-derive/Cargo.toml
Expand Up @@ -17,6 +17,7 @@ quote = "1.0.8"
syn = { version = "1.0.57", features = ["extra-traits"] }
Inflector = "0.11.4"
serde_json = "1.0.61"
darling = "0.12.1"

[lib]
proc-macro = true
Expand All @@ -31,3 +32,4 @@ serde_yaml = "0.8.14"
k8s-openapi = { version = "0.11.0", default-features = false, features = ["v1_20"] }
schemars = { version = "0.8.0", features = ["chrono"] }
chrono = "0.4.19"
trybuild = "1.0"
742 changes: 309 additions & 433 deletions kube-derive/src/custom_resource.rs

Large diffs are not rendered by default.

40 changes: 1 addition & 39 deletions kube-derive/src/lib.rs
Expand Up @@ -4,46 +4,8 @@
#![recursion_limit = "1024"]
extern crate proc_macro;
#[macro_use] extern crate quote;
use proc_macro::TokenStream;
use syn::Result;

trait CustomDerive: Sized {
fn parse(input: syn::DeriveInput, tokens: proc_macro2::TokenStream) -> Result<Self>;
fn emit(self) -> Result<proc_macro2::TokenStream>;
}

fn run_custom_derive<T>(input: TokenStream) -> TokenStream
where
T: CustomDerive,
{
let input: proc_macro2::TokenStream = input.into();
let tokens = input.clone();
let token_stream = match syn::parse2(input)
.and_then(|input| <T as CustomDerive>::parse(input, tokens))
.and_then(<T as CustomDerive>::emit)
{
Ok(token_stream) => token_stream,
Err(err) => err.to_compile_error(),
};
token_stream.into()
}

trait ResultExt<T> {
fn spanning(self, spanned: impl quote::ToTokens) -> Result<T>;
}

impl<T, E> ResultExt<T> for std::result::Result<T, E>
where
E: std::fmt::Display,
{
fn spanning(self, spanned: impl quote::ToTokens) -> Result<T> {
self.map_err(|err| syn::Error::new_spanned(spanned, err))
}
}

// #[derive(CustomResource)]
mod custom_resource;
use custom_resource::CustomResource;

/// A custom derive for kubernetes custom resource definitions.
///
Expand Down Expand Up @@ -214,5 +176,5 @@ use custom_resource::CustomResource;
/// [`k8s_openapi::Resource`]: https://docs.rs/k8s-openapi/*/k8s_openapi/trait.Resource.html
#[proc_macro_derive(CustomResource, attributes(kube))]
pub fn derive_custom_resource(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
run_custom_derive::<CustomResource>(input)
custom_resource::derive(proc_macro2::TokenStream::from(input)).into()
}
10 changes: 10 additions & 0 deletions kube-derive/tests/test_ui.rs
@@ -0,0 +1,10 @@
// Test that `kube-derive` outputs helpful error messages.
// If you make a change, remove `tests/ui/*.stderr` and run `cargo test`.
// Then copy the files that appear under `wip/` if it's what you expected.
// Alternatively, run `TRYBUILD=overwrite cargo test`.
// See https://github.com/dtolnay/trybuild
#[test]
fn test_failures() {
let t = trybuild::TestCases::new();
t.compile_fail("tests/ui/*.rs");
}
10 changes: 10 additions & 0 deletions kube-derive/tests/ui/enum_fails.rs
@@ -0,0 +1,10 @@
use kube_derive::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
enum FooSpec {
Foo,
}

fn main() {}
5 changes: 5 additions & 0 deletions kube-derive/tests/ui/enum_fails.stderr
@@ -0,0 +1,5 @@
error: Enums or Unions can not #[derive(CustomResource)]
--> $DIR/enum_fails.rs:6:6
|
6 | enum FooSpec {
| ^^^^^^^
11 changes: 11 additions & 0 deletions kube-derive/tests/ui/fail_with_suggestion.rs
@@ -0,0 +1,11 @@
use kube_derive::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[kube(group = "clux.dev", version = "v1", kind = "Foo", shortnames = "foo")]
struct FooSpec {
foo: String,
}

fn main() {}
5 changes: 5 additions & 0 deletions kube-derive/tests/ui/fail_with_suggestion.stderr
@@ -0,0 +1,5 @@
error: Unknown field: `shortnames`. Did you mean `shortname`?
--> $DIR/fail_with_suggestion.rs:6:58
|
6 | #[kube(group = "clux.dev", version = "v1", kind = "Foo", shortnames = "foo")]
| ^^^^^^^^^^
10 changes: 10 additions & 0 deletions kube-derive/tests/ui/missing_required.rs
@@ -0,0 +1,10 @@
use kube_derive::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

#[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
struct FooSpec {
foo: String,
}

fn main() {}
23 changes: 23 additions & 0 deletions kube-derive/tests/ui/missing_required.stderr
@@ -0,0 +1,23 @@
error: Missing field `group`
--> $DIR/missing_required.rs:5:10
|
5 | #[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
| ^^^^^^^^^^^^^^
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: Missing field `version`
--> $DIR/missing_required.rs:5:10
|
5 | #[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
| ^^^^^^^^^^^^^^
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: Missing field `kind`
--> $DIR/missing_required.rs:5:10
|
5 | #[derive(CustomResource, Serialize, Deserialize, Debug, Clone, JsonSchema)]
| ^^^^^^^^^^^^^^
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

0 comments on commit c7e0b97

Please sign in to comment.