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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,6 @@ mod data;
mod data_stream; mod data_stream;
mod from_data; mod from_data;
mod limits; mod limits;
mod temp_file;
pub use self::data::Data; pub use self::data::Data;
pub use self::data_stream::DataStream; 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::limits::Limits;
pub use self::capped::{N, Capped}; pub use self::capped::{N, Capped};
pub use ubyte::{ByteUnit, ToByteUnit}; pub use ubyte::{ByteUnit, ToByteUnit};
pub use temp_file::TempFile;
pub(crate) use self::data_stream::StreamReader; pub(crate) use self::data_stream::StreamReader;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,8 +8,33 @@ use crate::request::Request;
use crate::response::{self, Responder}; use crate::response::{self, Responder};
use crate::http::ContentType; use crate::http::ContentType;
/// A file with an associated name; responds with the Content-Type based on the /// A [`Responder`] that sends a file with a Content-Type based on its name.
/// file extension. ///
/// # 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)] #[derive(Debug)]
pub struct NamedFile(PathBuf, File); pub struct NamedFile(PathBuf, File);
@ -26,7 +51,7 @@ impl NamedFile {
/// ///
/// ```rust /// ```rust
/// # use rocket::get; /// # use rocket::get;
/// use rocket::response::NamedFile; /// use rocket::fs::NamedFile;
/// ///
/// #[get("/")] /// #[get("/")]
/// async fn index() -> Option<NamedFile> { /// async fn index() -> Option<NamedFile> {
@ -47,7 +72,7 @@ impl NamedFile {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use rocket::response::NamedFile; /// use rocket::fs::NamedFile;
/// ///
/// # async fn f() -> std::io::Result<()> { /// # async fn f() -> std::io::Result<()> {
/// let named_file = NamedFile::open("index.html").await?; /// let named_file = NamedFile::open("index.html").await?;
@ -65,7 +90,7 @@ impl NamedFile {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use rocket::response::NamedFile; /// use rocket::fs::NamedFile;
/// ///
/// # async fn f() -> std::io::Result<()> { /// # async fn f() -> std::io::Result<()> {
/// let mut named_file = NamedFile::open("index.html").await?; /// let mut named_file = NamedFile::open("index.html").await?;
@ -83,7 +108,7 @@ impl NamedFile {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use rocket::response::NamedFile; /// use rocket::fs::NamedFile;
/// ///
/// # async fn f() -> std::io::Result<()> { /// # async fn f() -> std::io::Result<()> {
/// let named_file = NamedFile::open("index.html").await?; /// let named_file = NamedFile::open("index.html").await?;
@ -101,7 +126,7 @@ impl NamedFile {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// use rocket::response::NamedFile; /// use rocket::fs::NamedFile;
/// ///
/// # async fn demo_path() -> std::io::Result<()> { /// # async fn demo_path() -> std::io::Result<()> {
/// let file = NamedFile::open("foo.txt").await?; /// let file = NamedFile::open("foo.txt").await?;

View File

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

View File

@ -1,23 +1,24 @@
use std::{io, mem}; use std::{io, mem};
use std::path::{PathBuf, Path}; use std::path::{PathBuf, Path};
use crate::Request;
use crate::http::{ContentType, Status}; use crate::http::{ContentType, Status};
use crate::data::{FromData, Data, Capped, N, Limits}; 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::outcome::IntoOutcome;
use crate::request::Request; use crate::fs::FileName;
use tokio::fs::{self, File}; use tokio::fs::{self, File};
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use tempfile::{NamedTempFile, TempPath}; use tempfile::{NamedTempFile, TempPath};
use either::Either; 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 /// `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 /// 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 /// when the `TempFile` handle is dropped unless it is persisted with
/// [`TempFile::persist_to()`]. /// [`TempFile::persist_to()`] or copied with [`TempFile::copy_to()`].
/// ///
/// # Hazards /// # Hazards
/// ///
@ -67,7 +68,7 @@ use either::Either;
/// ///
/// ```rust /// ```rust
/// # use rocket::post; /// # use rocket::post;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// ///
/// #[post("/upload", data = "<file>")] /// #[post("/upload", data = "<file>")]
/// async fn upload(mut file: TempFile<'_>) -> std::io::Result<()> { /// async fn upload(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -80,7 +81,7 @@ use either::Either;
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// use rocket::form::Form; /// use rocket::form::Form;
/// ///
/// #[derive(FromForm)] /// #[derive(FromForm)]
@ -147,7 +148,7 @@ impl<'v> TempFile<'v> {
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// ///
/// #[post("/", data = "<file>")] /// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> { /// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -216,7 +217,7 @@ impl<'v> TempFile<'v> {
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// ///
/// #[post("/", data = "<file>")] /// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> { /// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -285,7 +286,7 @@ impl<'v> TempFile<'v> {
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// ///
/// #[post("/", data = "<file>")] /// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> { /// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -319,7 +320,7 @@ impl<'v> TempFile<'v> {
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// ///
/// #[post("/", data = "<file>")] /// #[post("/", data = "<file>")]
/// fn handler(file: TempFile<'_>) { /// fn handler(file: TempFile<'_>) {
@ -342,7 +343,7 @@ impl<'v> TempFile<'v> {
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// ///
/// #[post("/", data = "<file>")] /// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> { /// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -381,7 +382,7 @@ impl<'v> TempFile<'v> {
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// ///
/// #[post("/", data = "<file>")] /// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> { /// async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
@ -402,7 +403,7 @@ impl<'v> TempFile<'v> {
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// ///
/// #[post("/", data = "<file>")] /// #[post("/", data = "<file>")]
/// async fn handle(mut file: TempFile<'_>) { /// async fn handle(mut file: TempFile<'_>) {
@ -424,7 +425,7 @@ impl<'v> TempFile<'v> {
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate rocket; /// # #[macro_use] extern crate rocket;
/// use rocket::data::TempFile; /// use rocket::fs::TempFile;
/// ///
/// #[post("/", data = "<file>")] /// #[post("/", data = "<file>")]
/// fn handle(file: TempFile<'_>) { /// fn handle(file: TempFile<'_>) {

View File

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

View File

@ -25,7 +25,6 @@
mod responder; mod responder;
mod redirect; mod redirect;
mod named_file;
mod response; mod response;
mod debug; mod debug;
mod body; mod body;
@ -44,7 +43,6 @@ pub use self::body::Body;
pub use self::responder::Responder; pub use self::responder::Responder;
pub use self::redirect::Redirect; pub use self::redirect::Redirect;
pub use self::flash::Flash; pub use self::flash::Flash;
pub use self::named_file::NamedFile;
pub use self::debug::Debug; pub use self::debug::Debug;
/// Type alias for the `Result` of a [`Responder::respond_to()`] call. /// 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 /// Responds with a streamed body containing the data in the `File`. No
/// `Content-Type` is set. To automatically have a `Content-Type` set based /// `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::http::{Status, ContentType};
use rocket::form::{Form, Contextual, FromForm, FromFormField, Context}; use rocket::form::{Form, Contextual, FromForm, FromFormField, Context};
use rocket::data::TempFile; use rocket::fs::TempFile;
use rocket::fs::{FileServer, relative}; use rocket::fs::{FileServer, relative};
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;

View File

@ -8,8 +8,8 @@ use std::{io, env};
use rocket::tokio::fs; use rocket::tokio::fs;
use rocket::data::{Capped, TempFile}; use rocket::data::Capped;
use rocket::response::NamedFile; use rocket::fs::{NamedFile, TempFile};
// Upload your `big_file.dat` by POSTing it to /upload. // Upload your `big_file.dat` by POSTing it to /upload.
// try `curl --data-binary @file.txt http://127.0.0.1:8000/stream/file` // 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`! // prefer to use `FileServer`!
mod manual { mod manual {
use std::path::{PathBuf, Path}; use std::path::{PathBuf, Path};
use rocket::response::NamedFile; use rocket::fs::NamedFile;
#[rocket::get("/second/<path..>")] #[rocket::get("/second/<path..>")]
pub async fn second(path: PathBuf) -> Option<NamedFile> { pub async fn second(path: PathBuf) -> Option<NamedFile> {

View File

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

View File

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

View File

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