Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add a fairing for CORS support #930

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 40 additions & 23 deletions contrib/codegen/build.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! This tiny build script ensures that rocket is not compiled with an
//! incompatible version of rust.

extern crate yansi;
extern crate version_check;
extern crate yansi;

use yansi::Color::{Red, Yellow, Blue};
use version_check::{supports_features, is_min_version, is_min_date};
use version_check::{is_min_date, is_min_version, supports_features};
use yansi::Color::{Blue, Red, Yellow};

// Specifies the minimum nightly version needed to compile Rocket.
const MIN_DATE: &'static str = "2018-10-05";
Expand All @@ -18,38 +18,55 @@ fn main() {
let triple = (ok_channel, ok_version, ok_date);

let print_version_err = |version: &str, date: &str| {
eprintln!("{} {}. {} {}.",
"Installed version is:",
Yellow.paint(format!("{} ({})", version, date)),
"Minimum required:",
Yellow.paint(format!("{} ({})", MIN_VERSION, MIN_DATE)));
eprintln!(
"{} {}. {} {}.",
"Installed version is:",
Yellow.paint(format!("{} ({})", version, date)),
"Minimum required:",
Yellow.paint(format!("{} ({})", MIN_VERSION, MIN_DATE))
);
};

if let (Some(ok_channel), Some((ok_version, version)), Some((ok_date, date))) = triple {
if !ok_channel {
eprintln!("{} {}",
Red.paint("Error:").bold(),
"Rocket requires a nightly or dev version of Rust.");
eprintln!(
"{} {}",
Red.paint("Error:").bold(),
"Rocket requires a nightly or dev version of Rust."
);
print_version_err(&*version, &*date);
eprintln!("{}{}{}",
Blue.paint("See the getting started guide ("),
"https://rocket.rs/v0.4/guide/getting-started/",
Blue.paint(") for more information."));
eprintln!(
"{}{}{}",
Blue.paint("See the getting started guide ("),
"https://rocket.rs/v0.4/guide/getting-started/",
Blue.paint(") for more information.")
);
panic!("Aborting compilation due to incompatible compiler.")
}

if !ok_version || !ok_date {
eprintln!("{} {}",
Red.paint("Error:").bold(),
"Rocket requires a more recent version of rustc.");
eprintln!("{}{}{}",
Blue.paint("Use `"), "rustup update",
Blue.paint("` or your preferred method to update Rust."));
eprintln!(
"{} {}",
Red.paint("Error:").bold(),
"Rocket requires a more recent version of rustc."
);
eprintln!(
"{}{}{}",
Blue.paint("Use `"),
"rustup update",
Blue.paint("` or your preferred method to update Rust.")
);
print_version_err(&*version, &*date);
panic!("Aborting compilation due to incompatible compiler.")
}
} else {
println!("cargo:warning={}", "Rocket was unable to check rustc compatibility.");
println!("cargo:warning={}", "Build may fail due to incompatible rustc version.");
println!(
"cargo:warning={}",
"Rocket was unable to check rustc compatibility."
);
println!(
"cargo:warning={}",
"Build may fail due to incompatible rustc version."
);
}
}
21 changes: 14 additions & 7 deletions contrib/codegen/src/database.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use devise::{Result, Spanned};
use proc_macro::TokenStream;
use devise::{Spanned, Result};
use syn::{DataStruct, Fields, Data, Type, LitStr, DeriveInput, Ident, Visibility};
use syn::{Data, DataStruct, DeriveInput, Fields, Ident, LitStr, Type, Visibility};

#[derive(Debug)]
struct DatabaseInvocation {
Expand All @@ -19,9 +19,9 @@ struct DatabaseInvocation {
const EXAMPLE: &str = "example: `struct MyDatabase(diesel::SqliteConnection);`";
const ONLY_ON_STRUCTS_MSG: &str = "`database` attribute can only be used on structs";
const ONLY_UNNAMED_FIELDS: &str = "`database` attribute can only be applied to \
structs with exactly one unnamed field";
structs with exactly one unnamed field";
const NO_GENERIC_STRUCTS: &str = "`database` attribute cannot be applied to structs \
with generics";
with generics";

fn parse_invocation(attr: TokenStream, input: TokenStream) -> Result<DatabaseInvocation> {
let attr_stream2 = ::proc_macro2::TokenStream::from(attr);
Expand All @@ -36,15 +36,21 @@ fn parse_invocation(attr: TokenStream, input: TokenStream) -> Result<DatabaseInv

let structure = match input.data {
Data::Struct(s) => s,
_ => return Err(input.span().error(ONLY_ON_STRUCTS_MSG))
_ => return Err(input.span().error(ONLY_ON_STRUCTS_MSG)),
};

let inner_type = match structure.fields {
Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => {
let first = fields.unnamed.first().expect("checked length");
first.value().ty.clone()
}
_ => return Err(structure.fields.span().error(ONLY_UNNAMED_FIELDS).help(EXAMPLE))
_ => {
return Err(structure
.fields
.span()
.error(ONLY_UNNAMED_FIELDS)
.help(EXAMPLE));
}
};

Ok(DatabaseInvocation {
Expand Down Expand Up @@ -153,5 +159,6 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea
}
}
}
}.into())
}
.into())
}
7 changes: 4 additions & 3 deletions contrib/codegen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![feature(proc_macro_span, proc_macro_diagnostic)]
#![feature(crate_visibility_modifier)]
#![recursion_limit="256"]
#![recursion_limit = "256"]

//! # Rocket Contrib - Code Generation
//! This crate implements the code generation portion of the Rocket Contrib
Expand Down Expand Up @@ -28,10 +28,11 @@ extern crate devise;
extern crate proc_macro;

#[allow(unused_imports)]
#[macro_use] extern crate quote;
#[macro_use]
extern crate quote;

#[allow(unused_imports)]
crate use devise::{syn, proc_macro2};
crate use devise::{proc_macro2, syn};

#[cfg(feature = "database_attribute")]
mod database;
Expand Down
66 changes: 45 additions & 21 deletions contrib/codegen/tests/compile-test.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
extern crate compiletest_rs as compiletest;

use std::path::{Path, PathBuf};
use std::{io, fs::Metadata, time::SystemTime};
use std::{fs::Metadata, io, time::SystemTime};

#[derive(Copy, Clone)]
enum Kind {
#[allow(dead_code)]
Dynamic,
Static
Static,
}

impl Kind {
fn extension(self) -> &'static str {
match self {
#[cfg(windows)] Kind::Dynamic => ".dll",
#[cfg(all(unix, target_os = "macos"))] Kind::Dynamic => ".dylib",
#[cfg(all(unix, not(target_os = "macos")))] Kind::Dynamic => ".so",
Kind::Static => ".rlib"
#[cfg(windows)]
Kind::Dynamic => ".dll",
#[cfg(all(unix, target_os = "macos"))]
Kind::Dynamic => ".dylib",
#[cfg(all(unix, not(target_os = "macos")))]
Kind::Dynamic => ".so",
Kind::Static => ".rlib",
}
}
}

fn target_path() -> PathBuf {
#[cfg(debug_assertions)] const ENVIRONMENT: &str = "debug";
#[cfg(not(debug_assertions))] const ENVIRONMENT: &str = "release";
#[cfg(debug_assertions)]
const ENVIRONMENT: &str = "debug";
#[cfg(not(debug_assertions))]
const ENVIRONMENT: &str = "release";

Path::new(env!("CARGO_MANIFEST_DIR"))
.parent().unwrap().parent().unwrap()
.parent()
.unwrap()
.parent()
.unwrap()
.join("target")
.join(ENVIRONMENT)
}
Expand All @@ -41,7 +49,8 @@ fn link_flag(flag: &str, lib: &str, rel_path: &[&str]) -> String {
}

fn best_time_for(metadata: &Metadata) -> SystemTime {
metadata.created()
metadata
.created()
.or_else(|_| metadata.modified())
.or_else(|_| metadata.accessed())
.unwrap_or_else(|_| SystemTime::now())
Expand All @@ -55,12 +64,18 @@ fn extern_dep(name: &str, kind: Kind) -> io::Result<String> {
for entry in deps_root.read_dir().expect("read_dir call failed") {
let entry = match entry {
Ok(entry) => entry,
Err(_) => continue
Err(_) => continue,
};

let filename = entry.file_name();
let filename = filename.to_string_lossy();
let lib_name = filename.split('.').next().unwrap().split('-').next().unwrap();
let lib_name = filename
.split('.')
.next()
.unwrap()
.split('-')
.next()
.unwrap();

if lib_name == dep_name && filename.ends_with(kind.extension()) {
if let Some(ref mut existing) = dep_path {
Expand All @@ -74,8 +89,14 @@ fn extern_dep(name: &str, kind: Kind) -> io::Result<String> {
}

let dep = dep_path.ok_or_else(|| io::Error::from(io::ErrorKind::NotFound))?;
let filename = dep.file_name().ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))?;
Ok(link_flag("--extern", name, &["deps", &filename.to_string_lossy()]))
let filename = dep
.file_name()
.ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))?;
Ok(link_flag(
"--extern",
name,
&["deps", &filename.to_string_lossy()],
))
}

fn run_mode(mode: &'static str, path: &'static str) {
Expand All @@ -84,13 +105,16 @@ fn run_mode(mode: &'static str, path: &'static str) {
config.src_base = format!("tests/{}", path).into();
config.clean_rmeta();

config.target_rustcflags = Some([
link_flag("-L", "crate", &[]),
link_flag("-L", "dependency", &["deps"]),
extern_dep("rocket_http", Kind::Static).expect("find http dep"),
extern_dep("rocket", Kind::Static).expect("find core dep"),
extern_dep("rocket_contrib", Kind::Static).expect("find contrib dep"),
].join(" "));
config.target_rustcflags = Some(
[
link_flag("-L", "crate", &[]),
link_flag("-L", "dependency", &["deps"]),
extern_dep("rocket_http", Kind::Static).expect("find http dep"),
extern_dep("rocket", Kind::Static).expect("find core dep"),
extern_dep("rocket_contrib", Kind::Static).expect("find contrib dep"),
]
.join(" "),
);

compiletest::run_tests(&config);
}
Expand Down
1 change: 1 addition & 0 deletions contrib/lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ tera_templates = ["tera", "templates"]
handlebars_templates = ["handlebars", "templates"]
helmet = ["time"]
serve = []
cors = []

# The barage of user-facing database features.
diesel_sqlite_pool = ["databases", "diesel/sqlite", "diesel/r2d2"]
Expand Down
Loading