introduce rustfmt (#919)

* introduce rustfmt

* Cargofmt on all sea-orm crates & examples

* Revert testing script

* cargo fmt --manifest-path sea-orm-rocket/Cargo.toml --all

* add a script for formatting

* add nightly component for formatting

* set timeout and manual nightly install  in github action

* add flag for manifest-path

Co-authored-by: Billy Chan <ccw.billy.123@gmail.com>
This commit is contained in:
kyoto7250 2022-08-01 19:30:43 +09:00 committed by GitHub
parent a2fbbc7a57
commit dd545441d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 190 additions and 96 deletions

View File

@ -140,6 +140,58 @@ jobs:
--
-D warnings
rustfmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
components: rustfmt
override: true
- name: Run rustfmt on `sea-orm` workspace
uses: actions-rs/cargo@v1
with:
command: fmt
args: >
--all
--
--check
- name: Run rustfmt on `sea-orm-cli`
uses: actions-rs/cargo@v1
with:
command: fmt
args: >
--manifest-path sea-orm-cli/Cargo.toml
--all
--
--check
- name: Run rustfmt on `sea-orm-migration`
uses: actions-rs/cargo@v1
with:
command: fmt
args: >
--manifest-path sea-orm-migration/Cargo.toml
--all
--
--check
- name: Run rustfmt on `sea-orm-rocket`
uses: actions-rs/cargo@v1
with:
command: fmt
args: >
--manifest-path sea-orm-rocket/Cargo.toml
--all
--
--check
compile-sqlite:
name: Compile SQLite
needs: init
@ -326,6 +378,7 @@ jobs:
name: Examples
runs-on: ubuntu-latest
needs: examples-matrix
timeout-minutes: 15
strategy:
fail-fast: false
max-parallel: 12
@ -352,6 +405,12 @@ jobs:
args: >
--manifest-path ${{ matrix.path }}
- name: check rustfmt
run: |
rustup override set nightly
rustup component add rustfmt
cargo +nightly fmt --manifest-path ${{ matrix.path }} --all -- --check
issues-matrix:
name: Issues Matrix
needs: init

24
build-tools/rustfmt.sh Normal file
View File

@ -0,0 +1,24 @@
#!/bin/bash
set -e
if [ -d ./build-tools ]; then
targets=(
"sea-orm-cli/Cargo.toml"
"sea-orm-codegen/Cargo.toml"
"sea-orm-macros/Cargo.toml"
"sea-orm-migration/Cargo.toml"
"sea-orm-rocket/Cargo.toml"
)
for target in "${targets[@]}"; do
echo "cargo +nightly fmt --manifest-path ${target} --all"
cargo +nightly fmt --manifest-path "${target}" --all
done
examples=(`find examples -type f -name 'Cargo.toml'`)
for example in "${examples[@]}"; do
echo "cargo +nightly fmt --manifest-path ${example} --all"
cargo +nightly fmt --manifest-path "${example}" --all
done
else
echo "Please execute this script from the repository root."
fi

View File

@ -163,7 +163,8 @@ async fn not_found(data: web::Data<AppState>, request: HttpRequest) -> Result<Ht
ctx.insert("uri", request.uri().path());
let template = &data.templates;
let body = template.render("error/404.html.tera", &ctx)
let body = template
.render("error/404.html.tera", &ctx)
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(body))

View File

@ -1,8 +1,8 @@
use proc_macro::TokenStream;
use devise::{DeriveGenerator, FromMeta, MapperBuild, Support, ValidatorBuild};
use devise::proc_macro2_diagnostics::SpanDiagnosticExt;
use devise::syn::{self, spanned::Spanned};
use devise::{DeriveGenerator, FromMeta, MapperBuild, Support, ValidatorBuild};
const ONE_DATABASE_ATTR: &str = "missing `#[database(\"name\")]` attribute";
const ONE_UNNAMED_FIELD: &str = "struct must have exactly one unnamed field";
@ -16,95 +16,89 @@ struct DatabaseAttribute {
pub fn derive_database(input: TokenStream) -> TokenStream {
DeriveGenerator::build_for(input, quote!(impl sea_orm_rocket::Database))
.support(Support::TupleStruct)
.validator(ValidatorBuild::new()
.struct_validate(|_, s| {
if s.fields.len() == 1 {
Ok(())
} else {
Err(s.span().error(ONE_UNNAMED_FIELD))
.validator(ValidatorBuild::new().struct_validate(|_, s| {
if s.fields.len() == 1 {
Ok(())
} else {
Err(s.span().error(ONE_UNNAMED_FIELD))
}
}))
.outer_mapper(MapperBuild::new().struct_map(|_, s| {
let pool_type = match &s.fields {
syn::Fields::Unnamed(f) => &f.unnamed[0].ty,
_ => unreachable!("Support::TupleStruct"),
};
let decorated_type = &s.ident;
let db_ty = quote_spanned!(decorated_type.span() =>
<#decorated_type as sea_orm_rocket::Database>
);
quote_spanned! { decorated_type.span() =>
impl From<#pool_type> for #decorated_type {
fn from(pool: #pool_type) -> Self {
Self(pool)
}
}
})
)
.outer_mapper(MapperBuild::new()
.struct_map(|_, s| {
let pool_type = match &s.fields {
syn::Fields::Unnamed(f) => &f.unnamed[0].ty,
_ => unreachable!("Support::TupleStruct"),
};
let decorated_type = &s.ident;
let db_ty = quote_spanned!(decorated_type.span() =>
<#decorated_type as sea_orm_rocket::Database>
);
impl std::ops::Deref for #decorated_type {
type Target = #pool_type;
quote_spanned! { decorated_type.span() =>
impl From<#pool_type> for #decorated_type {
fn from(pool: #pool_type) -> Self {
Self(pool)
}
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::ops::Deref for #decorated_type {
type Target = #pool_type;
fn deref(&self) -> &Self::Target {
&self.0
}
impl std::ops::DerefMut for #decorated_type {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl std::ops::DerefMut for #decorated_type {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[rocket::async_trait]
impl<'r> rocket::request::FromRequest<'r> for &'r #decorated_type {
type Error = ();
#[rocket::async_trait]
impl<'r> rocket::request::FromRequest<'r> for &'r #decorated_type {
type Error = ();
async fn from_request(
req: &'r rocket::request::Request<'_>
) -> rocket::request::Outcome<Self, Self::Error> {
match #db_ty::fetch(req.rocket()) {
Some(db) => rocket::outcome::Outcome::Success(db),
None => rocket::outcome::Outcome::Failure((
rocket::http::Status::InternalServerError, ()))
}
}
}
impl rocket::Sentinel for &#decorated_type {
fn abort(rocket: &rocket::Rocket<rocket::Ignite>) -> bool {
#db_ty::fetch(rocket).is_none()
async fn from_request(
req: &'r rocket::request::Request<'_>
) -> rocket::request::Outcome<Self, Self::Error> {
match #db_ty::fetch(req.rocket()) {
Some(db) => rocket::outcome::Outcome::Success(db),
None => rocket::outcome::Outcome::Failure((
rocket::http::Status::InternalServerError, ()))
}
}
}
})
)
impl rocket::Sentinel for &#decorated_type {
fn abort(rocket: &rocket::Rocket<rocket::Ignite>) -> bool {
#db_ty::fetch(rocket).is_none()
}
}
}
}))
.outer_mapper(quote!(#[rocket::async_trait]))
.inner_mapper(MapperBuild::new()
.try_struct_map(|_, s| {
let db_name = DatabaseAttribute::one_from_attrs("database", &s.attrs)?
.map(|attr| attr.name)
.ok_or_else(|| s.span().error(ONE_DATABASE_ATTR))?;
.inner_mapper(MapperBuild::new().try_struct_map(|_, s| {
let db_name = DatabaseAttribute::one_from_attrs("database", &s.attrs)?
.map(|attr| attr.name)
.ok_or_else(|| s.span().error(ONE_DATABASE_ATTR))?;
let fairing_name = format!("'{}' Database Pool", db_name);
let fairing_name = format!("'{}' Database Pool", db_name);
let pool_type = match &s.fields {
syn::Fields::Unnamed(f) => &f.unnamed[0].ty,
_ => unreachable!("Support::TupleStruct"),
};
let pool_type = match &s.fields {
syn::Fields::Unnamed(f) => &f.unnamed[0].ty,
_ => unreachable!("Support::TupleStruct"),
};
Ok(quote_spanned! { pool_type.span() =>
type Pool = #pool_type;
Ok(quote_spanned! { pool_type.span() =>
type Pool = #pool_type;
const NAME: &'static str = #db_name;
const NAME: &'static str = #db_name;
fn init() -> sea_orm_rocket::Initializer<Self> {
sea_orm_rocket::Initializer::with_name(#fairing_name)
}
})
fn init() -> sea_orm_rocket::Initializer<Self> {
sea_orm_rocket::Initializer::with_name(#fairing_name)
}
})
)
}))
.to_tokens()
}

View File

@ -1,4 +1,4 @@
#![recursion_limit="256"]
#![recursion_limit = "256"]
#![warn(rust_2018_idioms)]
//! # `sea_orm_rocket` - Code Generation
@ -7,7 +7,8 @@
//! is an implementation detail. This create should never be depended on
//! directly.
#[macro_use] extern crate quote;
#[macro_use]
extern crate quote;
mod database;

View File

@ -29,14 +29,16 @@ use rocket::serde::{Deserialize, Serialize};
/// # use rocket::launch;
/// #[launch]
/// fn rocket() -> _ {
/// let figment = rocket::Config::figment()
/// .merge(("databases.name", sea_orm_rocket::Config {
/// let figment = rocket::Config::figment().merge((
/// "databases.name",
/// sea_orm_rocket::Config {
/// url: "db:specific@config&url".into(),
/// min_connections: None,
/// max_connections: 1024,
/// connect_timeout: 3,
/// idle_timeout: None,
/// }));
/// },
/// ));
///
/// rocket::custom(figment)
/// }

View File

@ -1,13 +1,13 @@
use std::marker::PhantomData;
use std::ops::{DerefMut};
use std::ops::DerefMut;
use rocket::{error, info_, Build, Ignite, Phase, Rocket, Sentinel};
use rocket::fairing::{self, Fairing, Info, Kind};
use rocket::request::{FromRequest, Outcome, Request};
use rocket::http::Status;
use rocket::request::{FromRequest, Outcome, Request};
use rocket::{error, info_, Build, Ignite, Phase, Rocket, Sentinel};
use rocket::yansi::Paint;
use rocket::figment::providers::Serialized;
use rocket::yansi::Paint;
use crate::Pool;
@ -31,7 +31,9 @@ use crate::Pool;
/// ```
///
/// See the [`Database` derive](derive@crate::Database) for details.
pub trait Database: From<Self::Pool> + DerefMut<Target = Self::Pool> + Send + Sync + 'static {
pub trait Database:
From<Self::Pool> + DerefMut<Target = Self::Pool> + Send + Sync + 'static
{
/// The [`Pool`] type of connections to this database.
///
/// When `Database` is derived, this takes the value of the `Inner` type in
@ -51,7 +53,7 @@ pub trait Database: From<Self::Pool> + DerefMut<Target = Self::Pool> + Send + Sy
/// ```rust
/// # mod _inner {
/// # use rocket::launch;
/// use sea_orm_rocket::{Database};
/// use sea_orm_rocket::Database;
/// # use sea_orm_rocket::MockPool as SeaOrmPool;
///
/// #[derive(Database)]
@ -90,10 +92,10 @@ pub trait Database: From<Self::Pool> + DerefMut<Target = Self::Pool> + Send + Sy
/// ```rust
/// # mod _inner {
/// # use rocket::launch;
/// use rocket::{Rocket, Build};
/// use rocket::fairing::{self, AdHoc};
/// use rocket::{Build, Rocket};
///
/// use sea_orm_rocket::{Database};
/// use sea_orm_rocket::Database;
/// # use sea_orm_rocket::MockPool as SeaOrmPool;
///
/// #[derive(Database)]
@ -124,8 +126,14 @@ pub trait Database: From<Self::Pool> + DerefMut<Target = Self::Pool> + Send + Sy
let dbtype = std::any::type_name::<Self>();
let fairing = Paint::default(format!("{}::init()", dbtype)).bold();
error!("Attempted to fetch unattached database `{}`.", Paint::default(dbtype).bold());
info_!("`{}` fairing must be attached prior to using this database.", fairing);
error!(
"Attempted to fetch unattached database `{}`.",
Paint::default(dbtype).bold()
);
info_!(
"`{}` fairing must be attached prior to using this database.",
fairing
);
None
}
}
@ -168,7 +176,6 @@ pub struct Initializer<D: Database>(Option<&'static str>, PhantomData<fn() -> D>
/// * If a connection is not available within `connect_timeout` seconds or
/// another error occurs, the gaurd _fails_ with status `ServiceUnavailable`
/// and the error is returned in `Some`.
///
pub struct Connection<'a, D: Database>(&'a <D::Pool as Pool>::Connection);
impl<D: Database> Initializer<D> {
@ -208,11 +215,13 @@ impl<D: Database> Fairing for Initializer<D> {
}
async fn on_ignite(&self, rocket: Rocket<Build>) -> fairing::Result {
let workers: usize = rocket.figment()
let workers: usize = rocket
.figment()
.extract_inner(rocket::Config::WORKERS)
.unwrap_or_else(|_| rocket::Config::default().workers);
let figment = rocket.figment()
let figment = rocket
.figment()
.focus(&format!("databases.{}", D::NAME))
.merge(Serialized::default("max_connections", workers * 4))
.merge(Serialized::default("connect_timeout", 5));

View File

@ -26,7 +26,11 @@ impl<A: fmt::Display, B: fmt::Display> fmt::Display for Error<A, B> {
}
impl<A, B> std::error::Error for Error<A, B>
where A: fmt::Debug + fmt::Display, B: fmt::Debug + fmt::Display {}
where
A: fmt::Debug + fmt::Display,
B: fmt::Debug + fmt::Display,
{
}
impl<A, B> From<crate::figment::Error> for Error<A, B> {
fn from(e: crate::figment::Error) -> Self {

View File

@ -7,14 +7,14 @@ pub use rocket::figment;
pub use rocket;
mod config;
mod database;
mod error;
mod pool;
mod config;
pub use self::config::Config;
pub use self::database::{Connection, Database, Initializer};
pub use self::error::Error;
pub use self::pool::{Pool, MockPool};
pub use self::config::Config;
pub use self::pool::{MockPool, Pool};
pub use sea_orm_rocket_codegen::*;