Move 'FileName', 'TempFile', 'NamedFile' to 'fs'.

This consolidates all file system related types into one module.
This commit is contained in:
Sergio Benitez 2021-05-22 16:21:19 -07:00
parent b1d05d20ac
commit a13a2f4a84
24 changed files with 92 additions and 61 deletions

View File

@ -667,7 +667,7 @@ pub fn derive_from_form(input: TokenStream) -> TokenStream {
/// # #[macro_use] extern crate rocket;
/// # use std::fs::File;
/// # use rocket::http::ContentType;
/// # use rocket::response::NamedFile;
/// # use rocket::fs::NamedFile;
/// # type Other = usize;
/// #
/// #[derive(Responder)]
@ -710,7 +710,7 @@ pub fn derive_from_form(input: TokenStream) -> TokenStream {
/// ```rust
/// # #[macro_use] extern crate rocket;
/// # use rocket::http::ContentType;
/// # use rocket::response::NamedFile;
/// # use rocket::fs::NamedFile;
/// # type Other = usize;
/// # type InnerResponder = String;
/// #

View File

@ -568,7 +568,7 @@ fn test_nested_multi() {
fn test_multipart() {
use rocket::http::ContentType;
use rocket::local::blocking::Client;
use rocket::data::TempFile;
use rocket::fs::TempFile;
#[derive(FromForm)]
struct MyForm<'r> {

View File

@ -41,7 +41,8 @@ impl std::ops::Deref for N {
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::{Capped, TempFile};
/// use rocket::data::Capped;
/// use rocket::fs::TempFile;
///
/// #[post("/upload", data = "<file>")]
/// async fn upload(mut file: Capped<TempFile<'_>>) -> std::io::Result<()> {
@ -58,7 +59,7 @@ impl std::ops::Deref for N {
/// [`DataStream`]: crate::data::DataStream
/// [`FromData`]: crate::data::FromData
/// [`FromForm`]: crate::form::FromForm
/// [`TempFile`]: crate::data::TempFile
/// [`TempFile`]: crate::fs::TempFile
// TODO: `Capped` not particularly usable outside Rocket due to coherence.
#[derive(Debug, Copy, Clone)]
pub struct Capped<T> {

View File

@ -67,7 +67,7 @@ use crate::http::uncased::Uncased;
/// | `json` | 1MiB | [`Json`] | JSON data and form payloads |
/// | `msgpack` | 1MiB | [`MsgPack`] | MessagePack data and form payloads |
///
/// [`TempFile`]: crate::data::TempFile
/// [`TempFile`]: crate::fs::TempFile
/// [`Json`]: crate::serde::json::Json
/// [`MsgPack`]: crate::serde::msgpack::MsgPack
///

View File

@ -6,7 +6,6 @@ mod data;
mod data_stream;
mod from_data;
mod limits;
mod temp_file;
pub use self::data::Data;
pub use self::data_stream::DataStream;
@ -14,6 +13,5 @@ pub use self::from_data::{FromData, Outcome};
pub use self::limits::Limits;
pub use self::capped::{N, Capped};
pub use ubyte::{ByteUnit, ToByteUnit};
pub use temp_file::TempFile;
pub(crate) use self::data_stream::StreamReader;

View File

@ -1,7 +1,7 @@
use crate::form::name::{NameView, FileName};
use crate::form::error::{Error, ErrorKind, Entity};
use crate::form::{name::NameView, error::{Error, ErrorKind, Entity}};
use crate::http::{ContentType, RawStr};
use crate::{Request, Data};
use crate::fs::FileName;
/// A form field with a string value.
///

View File

@ -129,7 +129,7 @@ use crate::http::uncased::AsUncased;
/// [`Lenient<T>`]: crate::form::Lenient
/// [`HashMap<K, V>`]: std::collections::HashMap
/// [`BTreeMap<K, V>`]: std::collections::BTreeMap
/// [`TempFile`]: crate::data::TempFile
/// [`TempFile`]: crate::fs::TempFile
/// [`Capped<C>`]: crate::data::Capped
/// [`time::DateTime`]: time::PrimitiveDateTime
/// [`IpAddr`]: std::net::IpAddr

View File

@ -4,10 +4,8 @@ mod name;
mod view;
mod key;
mod buf;
mod file_name;
pub use name::Name;
pub use view::NameView;
pub use key::Key;
pub use buf::NameBuf;
pub use file_name::FileName;

View File

@ -183,7 +183,7 @@ impl<'r, 'i> MultipartParser<'r, 'i> {
content_type,
request: self.request,
name: NameView::new(name),
file_name: file_name.map(FileName::new),
file_name: file_name.map(crate::fs::FileName::new),
data: Data::from(field),
})
} else {

View File

@ -86,7 +86,7 @@ use std::fmt::Debug;
use crate::data::ByteUnit;
use rocket_http::ContentType;
use crate::{data::TempFile, form::{Result, Error}};
use crate::{fs::TempFile, form::{Result, Error}};
crate::export! {
/// A helper macro for custom validation error messages.
@ -360,7 +360,8 @@ impl<L, T: Len<L>> Len<L> for Result<'_, T> {
/// ```rust
/// use rocket::http::ContentType;
/// use rocket::form::{FromForm, FromFormField};
/// use rocket::data::{TempFile, ToByteUnit};
/// use rocket::data::ToByteUnit;
/// use rocket::fs::TempFile;
///
/// #[derive(FromForm)]
/// struct Foo<'r> {
@ -724,8 +725,9 @@ pub fn one_of<'v, V, I, R>(value: V, items: R) -> Result<'v, ()>
///
/// ```rust
/// use rocket::form::FromForm;
/// use rocket::data::{ToByteUnit, TempFile};
/// use rocket::data::ToByteUnit;
/// use rocket::http::ContentType;
/// use rocket::fs::TempFile;
///
/// #[derive(FromForm)]
/// struct Foo<'r> {

View File

@ -2,7 +2,7 @@ use ref_cast::RefCast;
use crate::http::RawStr;
/// A file name in a file attachment or multipart [`DataField`].
/// A file name in a [`TempFile`] or multipart [`DataField`].
///
/// A `Content-Disposition` header, either in a response or a multipart field,
/// can optionally specify a `filename` directive as identifying information for
@ -21,8 +21,9 @@ use crate::http::RawStr;
/// may also prefer to avoid the value in the directive entirely by using a
/// safe, application-generated name instead.
///
/// [`TempFile::name()`]: crate::data::TempFile::name
/// [`TempFile::name()`]: crate::fs::TempFile::name
/// [`DataField`]: crate::form::DataField
/// [`TempFile`]: crate::fs::TempFile
#[repr(transparent)]
#[derive(RefCast, Debug)]
pub struct FileName(str);
@ -33,7 +34,7 @@ impl FileName {
/// # Example
///
/// ```rust
/// use rocket::form::name::FileName;
/// use rocket::fs::FileName;
///
/// let name = FileName::new("some-file.txt");
/// assert_eq!(name.as_str(), Some("some-file"));
@ -72,7 +73,7 @@ impl FileName {
/// # Example
///
/// ```rust
/// use rocket::form::name::FileName;
/// use rocket::fs::FileName;
///
/// let name = FileName::new("some-file.txt");
/// assert_eq!(name.as_str(), Some("some-file"));
@ -177,7 +178,7 @@ impl FileName {
/// # Example
///
/// ```rust
/// use rocket::form::name::FileName;
/// use rocket::fs::FileName;
///
/// let name = FileName::new("some-file.txt");
/// assert_eq!(name.as_str(), Some("some-file"));
@ -216,7 +217,7 @@ impl FileName {
/// # Example
///
/// ```rust
/// use rocket::form::name::FileName;
/// use rocket::fs::FileName;
///
/// let name = FileName::new("some-file.txt");
/// assert_eq!(name.dangerous_unsafe_unsanitized_raw(), "some-file.txt");

View File

@ -1,6 +1,12 @@
//! File serving, file accepting, and file system types.
//! File serving, file accepting, and file metadata types.
mod server;
mod named_file;
mod temp_file;
mod file_name;
pub use server::*;
pub use named_file::*;
pub use temp_file::*;
pub use file_name::*;
pub use server::relative;

View File

@ -8,8 +8,33 @@ use crate::request::Request;
use crate::response::{self, Responder};
use crate::http::ContentType;
/// A file with an associated name; responds with the Content-Type based on the
/// file extension.
/// A [`Responder`] that sends a file with a Content-Type based on its name.
///
/// # Example
///
/// A simple static file server mimicking [`FileServer`]:
///
/// ```rust
/// # use rocket::get;
/// use std::path::{PathBuf, Path};
///
/// use rocket::fs::{NamedFile, relative};
///
/// #[get("/file/<path..>")]
/// pub async fn second(path: PathBuf) -> Option<NamedFile> {
/// let mut path = Path::new(relative!("static")).join(path);
/// if path.is_dir() {
/// path.push("index.html");
/// }
///
/// NamedFile::open(path).await.ok()
/// }
/// ```
///
/// Always prefer to use [`FileServer`] which has more functionality and a
/// pithier API.
///
/// [`FileServer`]: crate::fs::FileServer
#[derive(Debug)]
pub struct NamedFile(PathBuf, File);
@ -26,7 +51,7 @@ impl NamedFile {
///
/// ```rust
/// # use rocket::get;
/// use rocket::response::NamedFile;
/// use rocket::fs::NamedFile;
///
/// #[get("/")]
/// async fn index() -> Option<NamedFile> {
@ -47,7 +72,7 @@ impl NamedFile {
/// # Example
///
/// ```rust
/// use rocket::response::NamedFile;
/// use rocket::fs::NamedFile;
///
/// # async fn f() -> std::io::Result<()> {
/// let named_file = NamedFile::open("index.html").await?;
@ -65,7 +90,7 @@ impl NamedFile {
/// # Example
///
/// ```rust
/// use rocket::response::NamedFile;
/// use rocket::fs::NamedFile;
///
/// # async fn f() -> std::io::Result<()> {
/// let mut named_file = NamedFile::open("index.html").await?;
@ -83,7 +108,7 @@ impl NamedFile {
/// # Example
///
/// ```rust
/// use rocket::response::NamedFile;
/// use rocket::fs::NamedFile;
///
/// # async fn f() -> std::io::Result<()> {
/// let named_file = NamedFile::open("index.html").await?;
@ -101,7 +126,7 @@ impl NamedFile {
/// # Examples
///
/// ```rust
/// use rocket::response::NamedFile;
/// use rocket::fs::NamedFile;
///
/// # async fn demo_path() -> std::io::Result<()> {
/// let file = NamedFile::open("foo.txt").await?;

View File

@ -2,8 +2,9 @@ use std::path::{PathBuf, Path};
use crate::{Request, Data};
use crate::http::{Method, uri::Segments, ext::IntoOwned};
use crate::response::{NamedFile, Redirect};
use crate::route::{Route, Handler, Outcome};
use crate::response::Redirect;
use crate::fs::NamedFile;
/// Custom handler for serving static files.
///

View File

@ -1,23 +1,24 @@
use std::{io, mem};
use std::path::{PathBuf, Path};
use crate::Request;
use crate::http::{ContentType, Status};
use crate::data::{FromData, Data, Capped, N, Limits};
use crate::form::{FromFormField, ValueField, DataField, error::Errors, name::FileName};
use crate::form::{FromFormField, ValueField, DataField, error::Errors};
use crate::outcome::IntoOutcome;
use crate::request::Request;
use crate::fs::FileName;
use tokio::fs::{self, File};
use tokio::io::AsyncWriteExt;
use tempfile::{NamedTempFile, TempPath};
use either::Either;
/// A file in temporary storage, deleted when dropped unless persisted.
/// A data and form guard that streams data into a temporary file.
///
/// `TempFile` is a data and form field (both value and data fields) guard that
/// streams incoming data into file in a temporary location. The file is deleted
/// when the `TempFile` handle is dropped. The file can be persisted with
/// [`TempFile::persist_to()`].
/// when the `TempFile` handle is dropped unless it is persisted with
/// [`TempFile::persist_to()`] or copied with [`TempFile::copy_to()`].
///
/// # Hazards
///
@ -67,7 +68,7 @@ use either::Either;
///
/// ```rust
/// # use rocket::post;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
///
/// #[post("/upload", data = "<file>")]
/// async fn upload(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -80,7 +81,7 @@ use either::Either;
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
/// use rocket::form::Form;
///
/// #[derive(FromForm)]
@ -147,7 +148,7 @@ impl<'v> TempFile<'v> {
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
///
/// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -216,7 +217,7 @@ impl<'v> TempFile<'v> {
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
///
/// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -285,7 +286,7 @@ impl<'v> TempFile<'v> {
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
///
/// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -319,7 +320,7 @@ impl<'v> TempFile<'v> {
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
///
/// #[post("/", data = "<file>")]
/// fn handler(file: TempFile<'_>) {
@ -342,7 +343,7 @@ impl<'v> TempFile<'v> {
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
///
/// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -381,7 +382,7 @@ impl<'v> TempFile<'v> {
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
///
/// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -402,7 +403,7 @@ impl<'v> TempFile<'v> {
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
///
/// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) {
@ -424,7 +425,7 @@ impl<'v> TempFile<'v> {
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile;
/// use rocket::fs::TempFile;
///
/// #[post("/", data = "<file>")]
/// fn handle(file: TempFile<'_>) {

View File

@ -18,7 +18,7 @@ use yansi::Paint;
/// use std::io;
///
/// # use rocket::get;
/// use rocket::response::NamedFile;
/// use rocket::fs::NamedFile;
///
/// #[get("/")]
/// async fn index() -> io::Result<NamedFile> {

View File

@ -25,7 +25,6 @@
mod responder;
mod redirect;
mod named_file;
mod response;
mod debug;
mod body;
@ -44,7 +43,6 @@ pub use self::body::Body;
pub use self::responder::Responder;
pub use self::redirect::Redirect;
pub use self::flash::Flash;
pub use self::named_file::NamedFile;
pub use self::debug::Debug;
/// Type alias for the `Result` of a [`Responder::respond_to()`] call.

View File

@ -69,7 +69,7 @@ use crate::request::Request;
///
/// Responds with a streamed body containing the data in the `File`. No
/// `Content-Type` is set. To automatically have a `Content-Type` set based
/// on the file's extension, use [`NamedFile`](crate::response::NamedFile).
/// on the file's extension, use [`NamedFile`](crate::fs::NamedFile).
///
/// * **()**
///

View File

@ -2,7 +2,7 @@
use rocket::http::{Status, ContentType};
use rocket::form::{Form, Contextual, FromForm, FromFormField, Context};
use rocket::data::TempFile;
use rocket::fs::TempFile;
use rocket::fs::{FileServer, relative};
use rocket_contrib::templates::Template;

View File

@ -8,8 +8,8 @@ use std::{io, env};
use rocket::tokio::fs;
use rocket::data::{Capped, TempFile};
use rocket::response::NamedFile;
use rocket::data::Capped;
use rocket::fs::{NamedFile, TempFile};
// Upload your `big_file.dat` by POSTing it to /upload.
// try `curl --data-binary @file.txt http://127.0.0.1:8000/stream/file`

View File

@ -6,7 +6,7 @@ use rocket::fs::{FileServer, relative};
// prefer to use `FileServer`!
mod manual {
use std::path::{PathBuf, Path};
use rocket::response::NamedFile;
use rocket::fs::NamedFile;
#[rocket::get("/second/<path..>")]
pub async fn second(path: PathBuf) -> Option<NamedFile> {

View File

@ -303,7 +303,7 @@ use rocket::response::Debug;
#[get("/blocking_task")]
async fn blocking_task() -> Result<Vec<u8>, Debug<io::Error>> {
// In a real app, use rocket::response::NamedFile or tokio::fs::File.
// In a real app, use rocket::fs::NamedFile or tokio::fs::File.
let vec = spawn_blocking(|| std::fs::read("data.txt")).await
.map_err(|e| io::Error::new(io::ErrorKind::Interrupted, e))??;

View File

@ -141,7 +141,7 @@ implemented in just 4 lines:
# fn main() {}
use std::path::{Path, PathBuf};
use rocket::response::NamedFile;
use rocket::fs::NamedFile;
#[get("/<file..>")]
async fn files(file: PathBuf) -> Option<NamedFile> {
@ -642,7 +642,7 @@ the be persisted. It makes accepting file uploads trivial:
```rust
# #[macro_use] extern crate rocket;
use rocket::data::TempFile;
use rocket::fs::TempFile;
#[post("/upload", format = "plain", data = "<file>")]
async fn upload(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -651,7 +651,7 @@ async fn upload(mut file: TempFile<'_>) -> std::io::Result<()> {
}
```
[`TempFile`]: @api/rocket/data/struct.TempFile.html
[`TempFile`]: @api/rocket/fs/struct.TempFile.html
### Streaming

View File

@ -227,7 +227,7 @@ found and a `404` when a file is not found in just 4, idiomatic lines:
# fn main() {}
# use std::path::{Path, PathBuf};
use rocket::response::NamedFile;
use rocket::fs::NamedFile;
#[get("/<file..>")]
async fn files(file: PathBuf) -> Option<NamedFile> {
@ -252,7 +252,7 @@ follows:
# fn main() {}
# use std::path::{Path, PathBuf};
use rocket::response::NamedFile;
use rocket::fs::NamedFile;
use rocket::response::status::NotFound;
#[get("/<file..>")]