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
|
//! Types for the F-Droid repository index.
use std::collections::HashMap;
use serde::{Deserialize, Deserializer};
pub(super) const PHONE_DEVICE_TYPE: &str = "phone";
pub(super) const EN_LOCALE: &str = "en-US";
#[derive(Debug, Deserialize)]
pub(super) struct Index {
pub(super) repo: Repo,
pub(super) packages: HashMap<String, Package>,
}
#[derive(Debug, Deserialize)]
pub(super) struct Repo {
pub(super) timestamp: u64,
}
#[derive(Debug, Deserialize)]
pub(super) struct Package {
pub(super) metadata: Metadata,
/// Releases keyed by the APK's SHA-256 digest.
pub(super) versions: HashMap<String, Version>,
}
#[derive(Debug, Deserialize)]
pub(super) struct Version {
/// Anti-feature explanations keyed first by anti-feature name and then by locale.
#[serde(default, rename = "antiFeatures")]
pub(super) anti_features: HashMap<AntiFeature, HashMap<String, String>>,
}
/// An [anti-feature](https://f-droid.org/docs/Anti-Features/).
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub(super) enum AntiFeature {
Ads,
DisabledAlgorithm,
KnownVuln,
NoSourceSince,
NonFreeAdd,
NonFreeAssets,
NonFreeDep,
NonFreeNet,
TetheredNet,
Tracking,
Other(String),
}
impl<'de> Deserialize<'de> for AntiFeature {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let name = String::deserialize(deserializer)?;
Ok(match name.as_str() {
"Ads" => Self::Ads,
"DisabledAlgorithm" => Self::DisabledAlgorithm,
"KnownVuln" => Self::KnownVuln,
"NoSourceSince" => Self::NoSourceSince,
"NonFreeAdd" => Self::NonFreeAdd,
"NonFreeAssets" => Self::NonFreeAssets,
"NonFreeDep" => Self::NonFreeDep,
"NonFreeNet" => Self::NonFreeNet,
"TetheredNet" => Self::TetheredNet,
"Tracking" => Self::Tracking,
_ => {
tracing::warn!("observed unknown F-Droid anti-feature {name}");
Self::Other(name)
}
})
}
}
#[derive(Debug, Deserialize)]
pub(super) struct Metadata {
pub(super) added: u64,
/// App names keyed by locale. Every package has an `en-US` name.
#[serde(default)]
pub(super) name: HashMap<String, String>,
/// Short app descriptions keyed by locale.
#[serde(default)]
pub(super) summary: HashMap<String, String>,
/// Screenshots keyed first by device type and then by locale.
#[serde(default)]
pub(super) screenshots: HashMap<String, HashMap<String, Vec<Screenshot>>>,
}
#[derive(Debug, Deserialize)]
pub(super) struct Screenshot {
/// Path to the screenshot relative to the repository address.
pub(super) name: String,
/// Screenshot file size in bytes, retained for enforcing upload limits.
#[allow(dead_code)]
pub(super) size: u64,
}
|