Repository: wafflespeanut/paperclip
Pull request #273 (2020-12-06 10:17:47)

Some code styling, thanks to nightly fmt and clippy
Apply some code styling and add them to the Makefile for the future!
Includes also some tiny logical changes. I'll highlight them with comments.
This change is so opinionated, feel free to comment or reject :D


Patch:
diff --git a/.travis.yml b/.travis.yml
index 4927935f..8251ba34 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,9 +33,10 @@ matrix:
     - cp -r book/_book/* target/doc/
   - name: check
     before_script:
-    - rustup component add rustfmt clippy
+    - rustup toolchain install nightly --allow-downgrade -c rustfmt
+    - rustup component add clippy
     script:
-    - cargo fmt --all -- --check
+    - cargo +nightly fmt --all -- --check
     - cargo clippy --all --features "actix" -- -D clippy::all
 
 deploy:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index be3c97d7..0f121ebe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Changed
 
 ### Fixed
+- Optional type aliases like `type Email = Option<String>` will not be added to the `required` fields.
 
 ## [0.5.0] - 2020-11-28
 ### Added
diff --git a/Makefile b/Makefile
index 285c6fef..a53842a5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,4 @@
-
-all: fmt build test
+all: check build test
 
 clean:
 	rm -rf Cargo.lock
@@ -12,9 +11,15 @@ prepare:
 	rustup override set stable
 	rustup component add rustfmt
 	rustup component add clippy
+	rustup toolchain install nightly --allow-downgrade -c rustfmt clippy
+
+check:
+	cargo +nightly fmt --all
+	cargo clippy --all --features "actix" -- -D clippy::all
 
-fmt:
-	cargo fmt --all
+check_nightly:
+	cargo +nightly fmt --all
+	cargo +nightly clippy --all --features "actix" -- -D clippy::all
 
 doc:
 	cargo doc --all --all-features --no-deps
@@ -25,7 +30,6 @@ build:
 	cargo build --features cli
 
 test:
-	cargo clippy --all --features "actix" -- -D clippy::all
 	cargo test --all --features "actix cli chrono uuid"
 	# Compile the code generated through tests.
 	cd tests/test_pet && cargo check
diff --git a/core/src/util.rs b/core/src/util.rs
index b91701e5..e89f5af3 100644
--- a/core/src/util.rs
+++ b/core/src/util.rs
@@ -1,7 +1,9 @@
-use std::future::Future;
-use std::marker::Unpin;
-use std::pin::Pin;
-use std::task::{Context, Poll};
+use std::{
+    future::Future,
+    marker::Unpin,
+    pin::Pin,
+    task::{Context, Poll},
+};
 
 /// Unstabilized [`Ready`](https://doc.rust-lang.org/nightly/std/future/struct.Ready.html) future.
 pub struct Ready<T>(Option<T>);
diff --git a/core/src/v2/actix.rs b/core/src/v2/actix.rs
index f9d60440..2f383796 100644
--- a/core/src/v2/actix.rs
+++ b/core/src/v2/actix.rs
@@ -1,10 +1,12 @@
-use super::models::{
-    DefaultOperationRaw, DefaultResponseRaw, DefaultSchemaRaw, Either, Parameter, ParameterIn,
-    Response, SecurityScheme,
-};
 #[cfg(feature = "actix-multipart")]
 use super::schema::TypedData;
-use super::schema::{Apiv2Errors, Apiv2Operation, Apiv2Schema};
+use super::{
+    models::{
+        DefaultOperationRaw, DefaultResponseRaw, DefaultSchemaRaw, Either, Parameter, ParameterIn,
+        Response, SecurityScheme,
+    },
+    schema::{Apiv2Errors, Apiv2Operation, Apiv2Schema},
+};
 use crate::util::{ready, Ready};
 use actix_web::{
     http::StatusCode,
@@ -17,11 +19,13 @@ use serde::Serialize;
 #[cfg(feature = "serde_qs")]
 use serde_qs::actix::QsQuery;
 
-use std::collections::BTreeMap;
-use std::fmt;
-use std::future::Future;
-use std::pin::Pin;
-use std::task::{Context, Poll};
+use std::{
+    collections::BTreeMap,
+    fmt,
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
 
 /// Actix-specific trait for indicating that this entity can modify an operation
 /// and/or update the global map of definitions.
diff --git a/core/src/v2/extensions.rs b/core/src/v2/extensions.rs
index 002afd63..0a5c9a18 100644
--- a/core/src/v2/extensions.rs
+++ b/core/src/v2/extensions.rs
@@ -1,11 +1,13 @@
 use serde::{Deserialize, Deserializer, Serialize, Serializer};
 
 use once_cell::sync::Lazy;
-use std::cmp::Ordering;
-use std::collections::BTreeMap;
-use std::fmt;
-use std::ops::{Deref, DerefMut};
-use std::sync::Arc;
+use std::{
+    cmp::Ordering,
+    collections::BTreeMap,
+    fmt,
+    ops::{Deref, DerefMut},
+    sync::Arc,
+};
 
 /// Media range for JSON.
 pub static JSON_MIME: Lazy<MediaRange> =
diff --git a/core/src/v2/mod.rs b/core/src/v2/mod.rs
index 423d5435..9771bf4a 100644
--- a/core/src/v2/mod.rs
+++ b/core/src/v2/mod.rs
@@ -14,8 +14,10 @@ pub use self::actix::{
     AcceptedJson, CreatedJson, NoContent, OperationModifier, ResponderWrapper, ResponseWrapper,
 };
 
-pub use self::models::{DefaultSchema, ResolvableApi};
-pub use self::schema::Schema;
+pub use self::{
+    models::{DefaultSchema, ResolvableApi},
+    schema::Schema,
+};
 pub use paperclip_macros::*;
 
 #[cfg(feature = "codegen")]
diff --git a/core/src/v2/models.rs b/core/src/v2/models.rs
index 4fa8fb5e..59e5d37b 100644
--- a/core/src/v2/models.rs
+++ b/core/src/v2/models.rs
@@ -14,11 +14,13 @@ use regex::{Captures, Regex};
 use actix_web::http::Method;
 
 use parking_lot::RwLock;
-use std::borrow::Cow;
-use std::collections::{BTreeMap, BTreeSet};
-use std::fmt::{self, Display};
-use std::ops::{Deref, DerefMut};
-use std::sync::Arc;
+use std::{
+    borrow::Cow,
+    collections::{BTreeMap, BTreeSet},
+    fmt::{self, Display},
+    ops::{Deref, DerefMut},
+    sync::Arc,
+};
 
 /// Regex that can be used for fetching templated path parameters.
 static PATH_TEMPLATE_REGEX: Lazy<Regex> =
diff --git a/core/src/v2/resolver.rs b/core/src/v2/resolver.rs
index d42485e5..65c01203 100644
--- a/core/src/v2/resolver.rs
+++ b/core/src/v2/resolver.rs
@@ -8,9 +8,7 @@ use super::{
 use crate::error::ValidationError;
 use heck::CamelCase;
 
-use std::cell::RefCell;
-use std::collections::BTreeMap;
-use std::mem;
+use std::{cell::RefCell, collections::BTreeMap, mem};
 
 // FIXME: The resolver is not in its best. It "just" works atm.
 
diff --git a/core/src/v2/schema.rs b/core/src/v2/schema.rs
index 9388c151..df765b31 100644
--- a/core/src/v2/schema.rs
+++ b/core/src/v2/schema.rs
@@ -250,6 +250,9 @@ pub trait Apiv2Schema {
     /// Description of this schema. In case the trait is derived, uses the documentation on the type.
     const DESCRIPTION: &'static str = "";
 
+    /// Indicates the requirement of this schema.
+    const REQUIRED: bool = true;
+
     /// Returns the raw schema for this object.
     fn raw_schema() -> DefaultSchemaRaw {
         Default::default()
@@ -294,16 +297,18 @@ impl Apiv2Schema for serde_yaml::Value {}
 
 impl<T: TypedData> Apiv2Schema for T {
     fn raw_schema() -> DefaultSchemaRaw {
-        let mut schema = DefaultSchemaRaw::default();
-        schema.data_type = Some(T::data_type());
-        schema.format = T::format();
-        schema
+        DefaultSchemaRaw {
+            data_type: Some(T::data_type()),
+            format: T::format(),
+            ..Default::default()
+        }
     }
 }
 
 #[cfg(feature = "nightly")]
 impl<T> Apiv2Schema for Option<T> {
     default const NAME: Option<&'static str> = None;
+    default const REQUIRED: bool = false;
 
     default fn raw_schema() -> DefaultSchemaRaw {
         Default::default()
@@ -316,6 +321,7 @@ impl<T> Apiv2Schema for Option<T> {
 
 impl<T: Apiv2Schema> Apiv2Schema for Option<T> {
     const NAME: Option<&'static str> = T::NAME;
+    const REQUIRED: bool = false;
 
     fn raw_schema() -> DefaultSchemaRaw {
         T::raw_schema()
@@ -373,10 +379,11 @@ macro_rules! impl_schema_array {
     ($ty:ty) => {
         impl<T: Apiv2Schema> Apiv2Schema for $ty {
             fn raw_schema() -> DefaultSchemaRaw {
-                let mut schema = DefaultSchemaRaw::default();
-                schema.data_type = Some(DataType::Array);
-                schema.items = Some(T::schema_with_ref().into());
-                schema
+                DefaultSchemaRaw {
+                    data_type: Some(DataType::Array),
+                    items: Some(T::schema_with_ref().into()),
+                    ..Default::default()
+                }
             }
         }
     };
@@ -386,10 +393,11 @@ macro_rules! impl_schema_map {
     ($ty:ty) => {
         impl<K: ToString, V: Apiv2Schema> Apiv2Schema for $ty {
             fn raw_schema() -> DefaultSchemaRaw {
-                let mut schema = DefaultSchemaRaw::default();
-                schema.data_type = Some(DataType::Object);
-                schema.extra_props = Some(Either::Right(V::schema_with_ref().into()));
-                schema
+                DefaultSchemaRaw {
+                    data_type: Some(DataType::Object),
+                    extra_props: Some(Either::Right(V::schema_with_ref().into())),
+                    ..Default::default()
+                }
             }
         }
     };
diff --git a/macros/src/actix.rs b/macros/src/actix.rs
index 46e30993..43232887 100644
--- a/macros/src/actix.rs
+++ b/macros/src/actix.rs
@@ -7,9 +7,9 @@ use lazy_static::lazy_static;
 use proc_macro::TokenStream;
 use quote::quote;
 use strum_macros::EnumString;
-use syn::spanned::Spanned;
 use syn::{
     punctuated::{Pair, Punctuated},
+    spanned::Spanned,
     Attribute, Data, DataEnum, DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed, FnArg,
     Generics, Ident, ItemFn, Lit, Meta, MetaList, MetaNameValue, NestedMeta, Path, PathArguments,
     ReturnType, Token, TraitBound, Type, TypeTraitObject,
@@ -769,29 +769,15 @@ fn add_optional_impl(name: &Ident, generics: &Generics) -> proc_macro2::TokenStr
     }
 }
 
-fn get_field_type(field: &Field) -> (Option<proc_macro2::TokenStream>, bool) {
-    let mut is_required = true;
+fn get_field_type(field: &Field) -> Option<proc_macro2::TokenStream> {
     match field.ty {
-        Type::Path(ref p) => {
-            let ty = p
-                .path
-                .segments
-                .last()
-                .expect("expected type for struct field");
-
-            if p.path.segments.len() == 1 && &ty.ident == "Option" {
-                is_required = false;
-            }
-
-            (Some(address_type_for_fn_call(&field.ty)), is_required)
-        }
-        Type::Reference(_) => (Some(address_type_for_fn_call(&field.ty)), is_required),
+        Type::Path(_) | Type::Reference(_) => Some(address_type_for_fn_call(&field.ty)),
         _ => {
             emit_warning!(
                 field.ty.span().unwrap(),
                 "unsupported field type will be ignored."
             );
-            (None, is_required)
+            None
         }
     }
 }
@@ -799,9 +785,8 @@ fn get_field_type(field: &Field) -> (Option<proc_macro2::TokenStream>, bool) {
 /// Generates code for a tuple struct with fields.
 fn handle_unnamed_field_struct(fields: &FieldsUnnamed, props_gen: &mut proc_macro2::TokenStream) {
     let field = fields.unnamed.iter().next().unwrap();
-    let (ty_ref, _) = get_field_type(&field);
 
-    if let Some(ty_ref) = ty_ref {
+    if let Some(ty_ref) = get_field_type(&field) {
         props_gen.extend(quote!({
             schema = #ty_ref::raw_schema();
         }));
@@ -809,9 +794,9 @@ fn handle_unnamed_field_struct(fields: &FieldsUnnamed, props_gen: &mut proc_macr
 }
 
 /// Checks for `api_v2_empty` attributes and removes them.
-fn extract_openapi_attrs<'a>(
-    field_attrs: &'a [Attribute],
-) -> impl Iterator<Item = Punctuated<syn::NestedMeta, syn::token::Comma>> + 'a {
+fn extract_openapi_attrs(
+    field_attrs: &'_ [Attribute],
+) -> impl Iterator<Item = Punctuated<syn::NestedMeta, syn::token::Comma>> + '_ {
     field_attrs.iter().filter_map(|a| match a.parse_meta() {
         Ok(Meta::List(list)) if list.path.is_ident("openapi") => Some(list.nested),
         _ => None,
@@ -877,7 +862,7 @@ fn handle_field_struct(
             field_name = prop.rename(&field_name);
         }
 
-        let (ty_ref, is_required) = get_field_type(&field);
+        let ty_ref = get_field_type(&field);
 
         let docs = extract_documentation(&field.attrs);
         let docs = docs.trim();
@@ -897,11 +882,11 @@ fn handle_field_struct(
             })
         };
 
-        if is_required {
-            gen.extend(quote! {
+        gen.extend(quote! {
+            if #ty_ref::REQUIRED {
                 schema.required.insert(#field_name.into());
-            });
-        }
+            }
+        });
 
         props_gen.extend(gen);
     }
diff --git a/macros/src/core.rs b/macros/src/core.rs
index f4e033b0..ea9f864a 100644
--- a/macros/src/core.rs
+++ b/macros/src/core.rs
@@ -2,8 +2,7 @@
 
 use proc_macro::TokenStream;
 use quote::quote;
-use syn::spanned::Spanned;
-use syn::{Data, DeriveInput, Fields, FieldsNamed, Ident};
+use syn::{spanned::Spanned, Data, DeriveInput, Fields, FieldsNamed, Ident};
 
 /// Actual parser and emitter for `api_v2_schema_struct` macro.
 pub fn emit_v2_schema_struct(input: TokenStream) -> TokenStream {
diff --git a/plugins/actix-web/src/lib.rs b/plugins/actix-web/src/lib.rs
index 65915ce4..736515d7 100644
--- a/plugins/actix-web/src/lib.rs
+++ b/plugins/actix-web/src/lib.rs
@@ -10,8 +10,11 @@ pub use paperclip_macros::{api_v2_errors, api_v2_operation, Apiv2Schema, Apiv2Se
 
 use self::web::{RouteWrapper, ServiceConfig};
 use actix_service::ServiceFactory;
-use actix_web::dev::{HttpServiceFactory, MessageBody, ServiceRequest, ServiceResponse, Transform};
-use actix_web::{web::HttpResponse, Error};
+use actix_web::{
+    dev::{HttpServiceFactory, MessageBody, ServiceRequest, ServiceResponse, Transform},
+    web::HttpResponse,
+    Error,
+};
 use futures::future::{ok as fut_ok, Ready};
 use paperclip_core::v2::models::{
     DefaultApiRaw, DefaultOperationRaw, DefaultPathItemRaw, DefaultSchemaRaw, HttpMethod,
@@ -19,10 +22,7 @@ use paperclip_core::v2::models::{
 };
 use parking_lot::RwLock;
 
-use std::collections::BTreeMap;
-use std::fmt::Debug;
-use std::future::Future;
-use std::sync::Arc;
+use std::{collections::BTreeMap, fmt::Debug, future::Future, sync::Arc};
 
 /// Wrapper for [`actix_web::App`](https://docs.rs/actix-web/*/actix_web/struct.App.html).
 pub struct App<T, B> {
diff --git a/plugins/actix-web/src/web.rs b/plugins/actix-web/src/web.rs
index 7c10e555..d7ec1c27 100644
--- a/plugins/actix-web/src/web.rs
+++ b/plugins/actix-web/src/web.rs
@@ -7,20 +7,20 @@ pub use actix_web::web::{
 
 use crate::Mountable;
 use actix_service::{IntoServiceFactory, ServiceFactory};
-use actix_web::dev::{
-    AppService, Factory, HttpServiceFactory, ServiceRequest, ServiceResponse, Transform,
+use actix_web::{
+    dev::{AppService, Factory, HttpServiceFactory, ServiceRequest, ServiceResponse, Transform},
+    guard::Guard,
+    http::Method,
+    Error, FromRequest, Responder,
 };
-use actix_web::guard::Guard;
-use actix_web::{http::Method, Error, FromRequest, Responder};
-use paperclip_core::v2::models::{
-    DefaultOperationRaw, DefaultPathItemRaw, DefaultSchemaRaw, HttpMethod, SecurityScheme,
+use paperclip_core::v2::{
+    models::{
+        DefaultOperationRaw, DefaultPathItemRaw, DefaultSchemaRaw, HttpMethod, SecurityScheme,
+    },
+    schema::Apiv2Operation,
 };
-use paperclip_core::v2::schema::Apiv2Operation;
 
-use std::collections::BTreeMap;
-use std::fmt::Debug;
-use std::future::Future;
-use std::mem;
+use std::{collections::BTreeMap, fmt::Debug, future::Future, mem};
 
 const METHODS: &[Method] = &[
     Method::GET,
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 00000000..b28f863e
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1,2 @@
+merge_imports = true
+space_after_colon = true
diff --git a/src/bin/main.rs b/src/bin/main.rs
index b2fb27aa..934f640d 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -1,14 +1,18 @@
 use anyhow::Error;
-use paperclip::v2::{
-    self,
-    codegen::{CrateMeta, DefaultEmitter, EmitMode, Emitter, EmitterState},
-    models::{DefaultSchema, ResolvableApi},
+use paperclip::{
+    v2::{
+        self,
+        codegen::{CrateMeta, DefaultEmitter, EmitMode, Emitter, EmitterState},
+        models::{DefaultSchema, ResolvableApi},
+    },
+    PaperClipError,
 };
-use paperclip::PaperClipError;
 use structopt::StructOpt;
 
-use std::fs::{self, File};
-use std::path::PathBuf;
+use std::{
+    fs::{self, File},
+    path::PathBuf,
+};
 
 fn parse_version(s: &str) -> Result<OApiVersion, Error> {
     match s {
diff --git a/src/build/build.rs b/src/build/build.rs
index ab897da0..5e9b4015 100644
--- a/src/build/build.rs
+++ b/src/build/build.rs
@@ -1,7 +1,9 @@
-use std::env;
-use std::fs::File;
-use std::io::{Read, Write};
-use std::path::PathBuf;
+use std::{
+    env,
+    fs::File,
+    io::{Read, Write},
+    path::PathBuf,
+};
 
 fn load_file(p: PathBuf) -> String {
     let mut string = String::new();
diff --git a/src/error.rs b/src/error.rs
index b6a453f7..69e1810d 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,5 +1,4 @@
-use std::collections::HashSet;
-use std::path::PathBuf;
+use std::{collections::HashSet, path::PathBuf};
 
 macro_rules! impl_err_from {
     ($err:ident :: $type:ty > $variant:ident) => {
diff --git a/src/lib.rs b/src/lib.rs
index 91f0210c..c454f549 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -21,8 +21,11 @@ pub use paperclip_macros::api_v2_schema_struct as api_v2_schema;
 pub mod actix {
     //! Plugin types, traits and macros for actix-web framework.
 
-    pub use paperclip_actix::{api_v2_errors, api_v2_operation, Apiv2Schema, Apiv2Security};
-    pub use paperclip_actix::{web, App, Mountable, OpenApiExt};
-    pub use paperclip_core::v2::{AcceptedJson, CreatedJson, NoContent};
-    pub use paperclip_core::v2::{OperationModifier, ResponderWrapper, ResponseWrapper};
+    pub use paperclip_actix::{
+        api_v2_errors, api_v2_operation, web, Apiv2Schema, Apiv2Security, App, Mountable,
+        OpenApiExt,
+    };
+    pub use paperclip_core::v2::{
+        AcceptedJson, CreatedJson, NoContent, OperationModifier, ResponderWrapper, ResponseWrapper,
+    };
 }
diff --git a/src/v2/codegen/author.rs b/src/v2/codegen/author.rs
index 475a1808..31ba85ba 100644
--- a/src/v2/codegen/author.rs
+++ b/src/v2/codegen/author.rs
@@ -3,8 +3,7 @@
 //! Obtained from [Cargo](https://github.com/rust-lang/cargo/blob/fa05862cd0c6b899b801fda0f256ac5b9bae69d9/src/cargo/ops/cargo_new.rs#L690-L750).
 
 use anyhow::Error;
-use git2::Config as GitConfig;
-use git2::Repository as GitRepository;
+use git2::{Config as GitConfig, Repository as GitRepository};
 
 use std::env;
 
diff --git a/src/v2/codegen/emitter.rs b/src/v2/codegen/emitter.rs
index 1db38bd2..383282a1 100644
--- a/src/v2/codegen/emitter.rs
+++ b/src/v2/codegen/emitter.rs
@@ -1,28 +1,35 @@
-use super::object::{
-    ApiObject, ObjectContainer, ObjectField, ObjectVariant, OpRequirement, Parameter, Response,
+use super::{
+    object::{
+        ApiObject, ObjectContainer, ObjectField, ObjectVariant, OpRequirement, Parameter, Response,
+    },
+    state::{ChildModule, EmitterState},
+    CrateMeta,
 };
-use super::state::{ChildModule, EmitterState};
-use super::CrateMeta;
-use crate::error::PaperClipError;
-use crate::v2::{
-    models::{
-        Coder, CollectionFormat, DataType, DataTypeFormat, Either, HttpMethod, Items, MediaRange,
-        ParameterIn, Reference, ResolvableApi, ResolvableOperation, ResolvableParameter,
-        ResolvablePathItem, ResolvableResponse, JSON_CODER, JSON_MIME, YAML_CODER, YAML_MIME,
+use crate::{
+    error::PaperClipError,
+    v2::{
+        models::{
+            Coder, CollectionFormat, DataType, DataTypeFormat, Either, HttpMethod, Items,
+            MediaRange, ParameterIn, Reference, ResolvableApi, ResolvableOperation,
+            ResolvableParameter, ResolvablePathItem, ResolvableResponse, JSON_CODER, JSON_MIME,
+            YAML_CODER, YAML_MIME,
+        },
+        Schema,
     },
-    Schema,
 };
 use anyhow::Error;
 use heck::{CamelCase, SnekCase};
 use http::{header::HeaderName, HeaderMap};
 use itertools::Itertools;
 use parking_lot::RwLock;
-use std::collections::{BTreeMap, BTreeSet, HashSet};
-use std::fmt::Debug;
-use std::fs;
-use std::ops::Deref;
-use std::path::{Path, PathBuf};
-use std::sync::Arc;
+use std::{
+    collections::{BTreeMap, BTreeSet, HashSet},
+    fmt::Debug,
+    fs,
+    ops::Deref,
+    path::{Path, PathBuf},
+    sync::Arc,
+};
 use url::Host;
 
 /// Identifier used for `Any` generic parameters in struct definitions.
diff --git a/src/v2/codegen/impls.rs b/src/v2/codegen/impls.rs
index beb7524d..fb40d178 100644
--- a/src/v2/codegen/impls.rs
+++ b/src/v2/codegen/impls.rs
@@ -1,12 +1,16 @@
-use super::emitter::ANY_GENERIC_PARAMETER;
-use super::object::{ApiObject, ApiObjectBuilder, Response, StructField, TypeParameters};
-use super::RUST_KEYWORDS;
+use super::{
+    emitter::ANY_GENERIC_PARAMETER,
+    object::{ApiObject, ApiObjectBuilder, Response, StructField, TypeParameters},
+    RUST_KEYWORDS,
+};
 use crate::v2::models::{CollectionFormat, ParameterIn, JSON_CODER, JSON_MIME};
 use heck::{CamelCase, KebabCase, SnekCase};
 
-use std::fmt::{self, Display, Write};
-use std::iter;
-use std::rc::Rc;
+use std::{
+    fmt::{self, Display, Write},
+    iter,
+    rc::Rc,
+};
 
 /// Represents the API object impl.
 pub struct ApiObjectImpl<'a> {
diff --git a/src/v2/codegen/mod.rs b/src/v2/codegen/mod.rs
index 4d8d514b..affd684d 100644
--- a/src/v2/codegen/mod.rs
+++ b/src/v2/codegen/mod.rs
@@ -8,13 +8,14 @@ pub mod object;
 mod state;
 include!(concat!(env!("OUT_DIR"), "/template.rs"));
 
-pub use self::emitter::{EmittedUnit, Emitter};
-pub use self::state::EmitterState;
+pub use self::{
+    emitter::{EmittedUnit, Emitter},
+    state::EmitterState,
+};
 
 use super::Schema;
 
-use std::fmt::Debug;
-use std::marker::PhantomData;
+use std::{fmt::Debug, marker::PhantomData};
 
 /// Common conflicting keywords in Rust. An underscore will be added
 /// to fields using these keywords.
diff --git a/src/v2/codegen/object.rs b/src/v2/codegen/object.rs
index e00f138e..d79bf2e6 100644
--- a/src/v2/codegen/object.rs
+++ b/src/v2/codegen/object.rs
@@ -5,17 +5,21 @@
 
 pub use super::impls::{ApiObjectBuilderImpl, ApiObjectImpl};
 
-use super::emitter::{ANY_GENERIC_PARAMETER, EXTRA_PROPS_FIELD, FILE_MARKER};
-use super::RUST_KEYWORDS;
+use super::{
+    emitter::{ANY_GENERIC_PARAMETER, EXTRA_PROPS_FIELD, FILE_MARKER},
+    RUST_KEYWORDS,
+};
 use crate::v2::models::{Coder, CollectionFormat, HttpMethod, ParameterIn};
 use heck::{CamelCase, SnekCase};
 use once_cell::sync::Lazy;
 use regex::{Captures, Regex};
 
-use std::collections::{BTreeMap, HashSet};
-use std::fmt::{self, Display, Write};
-use std::iter;
-use std::sync::Arc;
+use std::{
+    collections::{BTreeMap, HashSet},
+    fmt::{self, Display, Write},
+    iter,
+    sync::Arc,
+};
 
 /// Regex for appropriate escaping in docs.
 static DOC_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"\[|\]").expect("invalid doc regex?"));
diff --git a/src/v2/codegen/state.rs b/src/v2/codegen/state.rs
index 042aab3f..20599b35 100644
--- a/src/v2/codegen/state.rs
+++ b/src/v2/codegen/state.rs
@@ -1,7 +1,12 @@
-use super::template::{self, TEMPLATE};
-use super::{object::ApiObject, CrateMeta, EmitMode};
-use crate::error::PaperClipError;
-use crate::v2::models::{Coders, SpecFormat};
+use super::{
+    object::ApiObject,
+    template::{self, TEMPLATE},
+    CrateMeta, EmitMode,
+};
+use crate::{
+    error::PaperClipError,
+    v2::models::{Coders, SpecFormat},
+};
 use anyhow::Error;
 use heck::CamelCase;
 #[cfg(feature = "cli")]
@@ -9,16 +14,18 @@ use heck::SnekCase;
 use itertools::Itertools;
 use url::Url;
 
-use std::cell::RefCell;
-use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
-use std::fmt::Write as _;
 #[cfg(feature = "cli")]
 use std::fs;
-use std::fs::OpenOptions;
-use std::hash::{Hash, Hasher};
-use std::io::Write;
-use std::path::{Path, PathBuf};
-use std::rc::Rc;
+use std::{
+    cell::RefCell,
+    collections::{BTreeMap, BTreeSet, HashMap, HashSet},
+    fmt::Write as _,
+    fs::OpenOptions,
+    hash::{Hash, Hasher},
+    io::Write,
+    path::{Path, PathBuf},
+    rc::Rc,
+};
 
 /// Holds the state for your schema emitter.
 #[derive(Debug)]
diff --git a/src/v2/mod.rs b/src/v2/mod.rs
index 01964c6b..6c1a1afb 100644
--- a/src/v2/mod.rs
+++ b/src/v2/mod.rs
@@ -94,9 +94,13 @@ use std::io::{Read, Seek, SeekFrom};
 
 #[cfg(feature = "codegen")]
 pub use self::codegen::{DefaultEmitter, Emitter, EmitterState};
-pub use paperclip_core::im;
-pub use paperclip_core::v2::models::{self, DefaultSchema, ResolvableApi};
-pub use paperclip_core::v2::schema::{self, Schema};
+pub use paperclip_core::{
+    im,
+    v2::{
+        models::{self, DefaultSchema, ResolvableApi},
+        schema::{self, Schema},
+    },
+};
 
 /// Deserialize the schema from the given reader. Currently, this only supports
 /// JSON and YAML formats.


Test patch:
diff --git a/tests/test_app.rs b/tests/test_app.rs
index 68a09332..69ddf537 100644
--- a/tests/test_app.rs
+++ b/tests/test_app.rs
@@ -5,25 +5,33 @@ extern crate serde_json;
 
 use actix_rt::System;
 use actix_service::ServiceFactory;
-use actix_web::dev::{MessageBody, Payload, ServiceRequest, ServiceResponse};
-use actix_web::{App, Error, FromRequest, HttpRequest, HttpServer, Responder};
+use actix_web::{
+    dev::{MessageBody, Payload, ServiceRequest, ServiceResponse},
+    App, Error, FromRequest, HttpRequest, HttpServer, Responder,
+};
 use futures::future::{ok as fut_ok, ready, Future, Ready};
 use once_cell::sync::Lazy;
-use paperclip::actix::{
-    api_v2_errors, api_v2_operation, web, Apiv2Schema, Apiv2Security, CreatedJson, NoContent,
-    OpenApiExt,
+use paperclip::{
+    actix::{
+        api_v2_errors, api_v2_operation, web, Apiv2Schema, Apiv2Security, CreatedJson, NoContent,
+        OpenApiExt,
+    },
+    v2::models::{DefaultApiRaw, Info, Tag},
 };
-use paperclip::v2::models::{DefaultApiRaw, Info, Tag};
 use parking_lot::Mutex;
 
-use std::collections::{BTreeMap, HashMap, HashSet};
-use std::sync::mpsc;
-use std::thread;
+use std::{
+    collections::{BTreeMap, HashMap, HashSet},
+    sync::mpsc,
+    thread,
+};
 use uuid_dev::Uuid;
 
 static CLIENT: Lazy<reqwest::blocking::Client> = Lazy::new(|| reqwest::blocking::Client::new());
 static PORTS: Lazy<Mutex<HashSet<u16>>> = Lazy::new(|| Mutex::new(HashSet::new()));
 
+type OptionalUuid = Option<uuid_dev::Uuid>;
+
 #[derive(Deserialize, Serialize, Apiv2Schema)]
 #[serde(rename_all = "lowercase")]
 enum PetClass {
@@ -44,7 +52,7 @@ struct Pet {
     birthday: chrono_dev::NaiveDate,
     updated_on: Option<chrono_dev::NaiveDateTime>,
     #[serde(rename = "uuid")]
-    uid: Option<uuid_dev::Uuid>,
+    uid: OptionalUuid,
 }
 
 impl Default for Pet {
diff --git a/tests/test_codegen.rs b/tests/test_codegen.rs
index 67e3daea..0e34429b 100644
--- a/tests/test_codegen.rs
+++ b/tests/test_codegen.rs
@@ -5,8 +5,7 @@ use paperclip::v2::{
 };
 
 use once_cell::sync::Lazy;
-use std::fs::File;
-use std::path::PathBuf;
+use std::{fs::File, path::PathBuf};
 
 static ROOT: Lazy<PathBuf> = Lazy::new(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")));
 static PET_SCHEMA: Lazy<ResolvableApi<DefaultSchema>> = Lazy::new(|| {