-
Notifications
You must be signed in to change notification settings - Fork 144
Expand file tree
/
Copy pathutils.rs
More file actions
114 lines (97 loc) · 2.52 KB
/
utils.rs
File metadata and controls
114 lines (97 loc) · 2.52 KB
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use async_recursion::async_recursion;
use futures::StreamExt;
use http_body_util::BodyDataStream;
use std::{fmt::Write, num::ParseIntError, path::Path};
use crate::{common::errors::new_io_error, Error};
use rand::{
distr::uniform::{SampleRange, SampleUniform},
Fill, Rng,
};
use sha2::Digest;
use tracing::debug;
pub fn rand_range<T, R>(range: R) -> T
where
T: SampleUniform,
R: SampleRange<T>,
{
let mut rng = rand::rng();
rng.random_range(range)
}
pub fn rand_fill<T>(buf: &mut T)
where
T: Fill + ?Sized,
{
let mut rng = rand::rng();
rng.fill(buf)
}
#[allow(dead_code)]
pub fn decode_hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
(0..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16))
.collect()
}
pub fn encode_hex(bytes: &[u8]) -> String {
let mut s = String::with_capacity(bytes.len() * 2);
for &b in bytes {
write!(&mut s, "{:02x}", b).unwrap();
}
s
}
pub fn sha256(bytes: &[u8]) -> Vec<u8> {
let mut hasher = sha2::Sha256::new();
hasher.update(bytes);
hasher.finalize().to_vec()
}
pub fn md5(bytes: &[u8]) -> Vec<u8> {
let mut hasher = md5::Md5::new();
hasher.update(bytes);
hasher.finalize().to_vec()
}
/// Default value true for bool on serde
/// use this if you don't want do deal with Option<bool>
/// Use Default::default() for false
pub fn default_bool_true() -> bool {
true
}
#[async_recursion]
pub async fn download<P>(
url: &str,
path: P,
http_client: &HttpClient,
) -> anyhow::Result<()>
where
P: AsRef<Path> + std::marker::Send,
{
use std::io::Write;
let uri = url.parse::<hyper::Uri>()?;
let mut out = std::fs::File::create(&path)?;
let res = http_client.get(uri).await?;
if res.status().is_redirection() {
return download(
res.headers()
.get("Location")
.ok_or(new_io_error(
format!("failed to download from {}", url).as_str(),
))?
.to_str()?,
path,
http_client,
)
.await;
}
if !res.status().is_success() {
return Err(Error::InvalidConfig(format!(
"data download failed: {}",
res.status()
))
.into());
}
debug!("downloading data to {}", path.as_ref().to_string_lossy());
let mut stream = BodyDataStream::new(res.into_body());
while let Some(chunk) = stream.next().await {
out.write_all(&chunk?)?;
}
Ok(())
}
use super::http::HttpClient;