-
Notifications
You must be signed in to change notification settings - Fork 196
/
file.rs
68 lines (64 loc) · 2.3 KB
/
file.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! Simple module to store files in database.
//!
//! docs.rs supports two ways of storing files: in a postgres database and in an S3 bucket.
//! It does not support storing files on disk because of the sheer number of files:
//! doing so would quickly run into file descriptor limits when running the web server.
//!
//! It's recommended that you use the S3 bucket in production to avoid running out of disk space.
//! However, postgres is still available for testing and backwards compatibility.
use crate::error::Result;
use crate::storage::{AsyncStorage, CompressionAlgorithm, CompressionAlgorithms};
use serde_json::Value;
use std::path::{Path, PathBuf};
use tracing::instrument;
/// Store all files in a directory and return [[mimetype, filename]] as Json
///
/// If there is an S3 Client configured, store files into an S3 bucket;
/// otherwise, stores files into the 'files' table of the local database.
///
/// The mimetype is detected using `magic`.
///
/// Note that this function is used for uploading both sources
/// and files generated by rustdoc.
pub async fn add_path_into_database<P: AsRef<Path>>(
storage: &AsyncStorage,
prefix: impl AsRef<Path>,
path: P,
) -> Result<(Value, CompressionAlgorithms)> {
let (file_list, algorithms) = storage.store_all(prefix.as_ref(), path.as_ref()).await?;
Ok((
file_list_to_json(file_list.into_iter().collect()),
algorithms,
))
}
#[instrument(skip(storage))]
pub async fn add_path_into_remote_archive<P: AsRef<Path> + std::fmt::Debug>(
storage: &AsyncStorage,
archive_path: &str,
path: P,
public_access: bool,
) -> Result<(Value, CompressionAlgorithm)> {
let (file_list, algorithm) = storage
.store_all_in_archive(archive_path, path.as_ref())
.await?;
if public_access {
storage.set_public_access(archive_path, true).await?;
}
Ok((
file_list_to_json(file_list.into_iter().collect()),
algorithm,
))
}
fn file_list_to_json(file_list: Vec<(PathBuf, String)>) -> Value {
Value::Array(
file_list
.into_iter()
.map(|(path, name)| {
Value::Array(vec![
Value::String(name),
Value::String(path.into_os_string().into_string().unwrap()),
])
})
.collect(),
)
}