|
70 | 70 | } |
71 | 71 | } |
72 | 72 |
|
73 | | - /// Create a [`FileStream`] from a file path. |
74 | | - /// |
75 | | - /// # Examples |
76 | | - /// |
77 | | - /// ``` |
78 | | - /// use axum::{ |
79 | | - /// http::StatusCode, |
80 | | - /// response::IntoResponse, |
81 | | - /// Router, |
82 | | - /// routing::get |
83 | | - /// }; |
84 | | - /// use axum_extra::response::file_stream::FileStream; |
85 | | - /// use tokio::fs::File; |
86 | | - /// use tokio_util::io::ReaderStream; |
87 | | - /// |
88 | | - /// async fn file_stream() -> impl IntoResponse { |
89 | | - /// FileStream::<ReaderStream<File>>::from_path("test.txt") |
90 | | - /// .await |
91 | | - /// .map_err(|e| (StatusCode::NOT_FOUND, format!("File not found: {e}"))) |
92 | | - /// } |
93 | | - /// |
94 | | - /// let app = Router::new().route("/file-stream", get(file_stream)); |
95 | | - /// # let _: Router = app; |
96 | | - /// ``` |
97 | | - pub async fn from_path(path: impl AsRef<Path>) -> io::Result<FileStream<ReaderStream<File>>> { |
98 | | - let file = File::open(&path).await?; |
99 | | - let mut content_size = None; |
100 | | - let mut file_name = None; |
101 | | - |
102 | | - if let Ok(metadata) = file.metadata().await { |
103 | | - content_size = Some(metadata.len()); |
104 | | - } |
105 | | - |
106 | | - if let Some(file_name_os) = path.as_ref().file_name() { |
107 | | - if let Some(file_name_str) = file_name_os.to_str() { |
108 | | - file_name = Some(file_name_str.to_owned()); |
109 | | - } |
110 | | - } |
111 | | - |
112 | | - Ok(FileStream { |
113 | | - stream: ReaderStream::new(file), |
114 | | - file_name, |
115 | | - content_size, |
116 | | - }) |
117 | | - } |
118 | | - |
119 | 73 | /// Set the file name of the [`FileStream`]. |
120 | 74 | /// |
121 | 75 | /// This adds the attachment `Content-Disposition` header with the given `file_name`. |
@@ -259,6 +213,53 @@ where |
259 | 213 | } |
260 | 214 | } |
261 | 215 |
|
| 216 | +// Split because the general impl requires to specify `S` and this one does not. |
| 217 | +impl FileStream<ReaderStream<File>> { |
| 218 | + /// Create a [`FileStream`] from a file path. |
| 219 | + /// |
| 220 | + /// # Examples |
| 221 | + /// |
| 222 | + /// ``` |
| 223 | + /// use axum::{ |
| 224 | + /// http::StatusCode, |
| 225 | + /// response::IntoResponse, |
| 226 | + /// Router, |
| 227 | + /// routing::get |
| 228 | + /// }; |
| 229 | + /// use axum_extra::response::file_stream::FileStream; |
| 230 | + /// |
| 231 | + /// async fn file_stream() -> impl IntoResponse { |
| 232 | + /// FileStream::from_path("test.txt") |
| 233 | + /// .await |
| 234 | + /// .map_err(|e| (StatusCode::NOT_FOUND, format!("File not found: {e}"))) |
| 235 | + /// } |
| 236 | + /// |
| 237 | + /// let app = Router::new().route("/file-stream", get(file_stream)); |
| 238 | + /// # let _: Router = app; |
| 239 | + /// ``` |
| 240 | + pub async fn from_path(path: impl AsRef<Path>) -> io::Result<Self> { |
| 241 | + let file = File::open(&path).await?; |
| 242 | + let mut content_size = None; |
| 243 | + let mut file_name = None; |
| 244 | + |
| 245 | + if let Ok(metadata) = file.metadata().await { |
| 246 | + content_size = Some(metadata.len()); |
| 247 | + } |
| 248 | + |
| 249 | + if let Some(file_name_os) = path.as_ref().file_name() { |
| 250 | + if let Some(file_name_str) = file_name_os.to_str() { |
| 251 | + file_name = Some(file_name_str.to_owned()); |
| 252 | + } |
| 253 | + } |
| 254 | + |
| 255 | + Ok(Self { |
| 256 | + stream: ReaderStream::new(file), |
| 257 | + file_name, |
| 258 | + content_size, |
| 259 | + }) |
| 260 | + } |
| 261 | +} |
| 262 | + |
262 | 263 | impl<S> IntoResponse for FileStream<S> |
263 | 264 | where |
264 | 265 | S: TryStream + Send + 'static, |
@@ -474,7 +475,7 @@ mod tests { |
474 | 475 | let app = Router::new().route( |
475 | 476 | "/from_path", |
476 | 477 | get(move || async move { |
477 | | - FileStream::<ReaderStream<File>>::from_path(Path::new("CHANGELOG.md")) |
| 478 | + FileStream::from_path(Path::new("CHANGELOG.md")) |
478 | 479 | .await |
479 | 480 | .unwrap() |
480 | 481 | .into_response() |
|
0 commit comments