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
use crate::release_channel::Channel;
use crate::{ManifestaError, TResult};
#[derive(Debug)]
pub struct MetaManifest {
manifests: Vec<ManifestSource>,
}
impl MetaManifest {
pub(crate) fn try_from_str<T: AsRef<str>>(item: T) -> TResult<Self> {
let item = item.as_ref();
let manifests = item
.lines()
.map(ManifestSource::try_from_str)
.collect::<TResult<Vec<_>>>()?;
Ok(Self { manifests })
}
pub fn manifests(&self) -> &[ManifestSource] {
&self.manifests
}
}
#[derive(Debug)]
pub struct ManifestSource {
url: String,
channel: Channel,
date: String,
}
impl ManifestSource {
pub(crate) fn try_from_str<T: AsRef<str>>(item: T) -> TResult<Self> {
let item = item.as_ref();
let channel = Self::parse_channel(item)?;
let date = Self::parse_date(item)?;
Ok(Self {
url: format!("https://{}", item),
channel,
date,
})
}
pub(crate) fn url(&self) -> &str {
&self.url
}
pub(crate) fn channel(&self) -> Channel {
self.channel
}
pub(crate) fn date(&self) -> &str {
&self.date
}
fn parse_date(input: &str) -> TResult<String> {
let date = input.get(26..36).ok_or(ManifestaError::ParseManifestDate)?;
Ok(date.to_string())
}
fn parse_channel(input: &str) -> TResult<Channel> {
Ok(if input.contains("beta") {
Channel::Beta
} else if input.contains("nightly") {
Channel::Nightly
} else if input.contains("stable") {
Channel::Stable
} else {
return Err(ManifestaError::ParseManifestSource);
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::dl::fetch_meta_manifest;
#[test]
fn test_parse_meta_manifest() {
let meta_file = fetch_meta_manifest().unwrap();
let buffer = meta_file.load().unwrap();
let meta_manifest = MetaManifest::try_from_str(String::from_utf8(buffer).unwrap());
assert!(meta_manifest.is_ok());
}
}