1use crate::types::*;
2
3pub trait WatchFileFormat {
5 type Entry: WatchEntry;
7
8 fn version(&self) -> u32;
10
11 fn entries(&self) -> Box<dyn Iterator<Item = Self::Entry> + '_>;
13
14 fn to_string(&self) -> String;
16}
17
18pub trait WatchEntry {
20 fn url(&self) -> String;
22
23 fn matching_pattern(&self) -> Option<String>;
25
26 fn version_policy(&self) -> Result<Option<crate::VersionPolicy>, ParseError>;
28
29 fn script(&self) -> Option<String>;
31
32 fn get_option(&self, key: &str) -> Option<String>;
34
35 fn has_option(&self, key: &str) -> bool;
37
38 fn component(&self) -> Option<String> {
42 self.get_option("component")
43 }
44
45 fn ctype(&self) -> Result<Option<ComponentType>, ParseError> {
47 self.get_option("ctype").map(|s| s.parse()).transpose()
48 }
49
50 fn compression(&self) -> Result<Option<Compression>, ParseError> {
52 self.get_option("compression")
53 .map(|s| s.parse())
54 .transpose()
55 }
56
57 fn repack(&self) -> bool {
59 self.has_option("repack")
60 }
61
62 fn repacksuffix(&self) -> Option<String> {
64 self.get_option("repacksuffix")
65 }
66
67 fn mode(&self) -> Result<Mode, ParseError> {
69 Ok(self
70 .get_option("mode")
71 .map(|s| s.parse())
72 .transpose()?
73 .unwrap_or_default())
74 }
75
76 fn pretty(&self) -> Result<Pretty, ParseError> {
78 Ok(self
79 .get_option("pretty")
80 .map(|s| s.parse())
81 .transpose()?
82 .unwrap_or_default())
83 }
84
85 fn date(&self) -> String {
87 self.get_option("date").unwrap_or_else(|| "%Y%m%d".into())
88 }
89
90 fn gitexport(&self) -> Result<GitExport, ParseError> {
92 Ok(self
93 .get_option("gitexport")
94 .map(|s| s.parse())
95 .transpose()?
96 .unwrap_or_default())
97 }
98
99 fn gitmode(&self) -> Result<GitMode, ParseError> {
101 Ok(self
102 .get_option("gitmode")
103 .map(|s| s.parse())
104 .transpose()?
105 .unwrap_or_default())
106 }
107
108 fn pgpmode(&self) -> Result<PgpMode, ParseError> {
110 Ok(self
111 .get_option("pgpmode")
112 .map(|s| s.parse())
113 .transpose()?
114 .unwrap_or_default())
115 }
116
117 fn searchmode(&self) -> Result<SearchMode, ParseError> {
119 Ok(self
120 .get_option("searchmode")
121 .map(|s| s.parse())
122 .transpose()?
123 .unwrap_or_default())
124 }
125
126 fn decompress(&self) -> bool {
128 self.has_option("decompress")
129 }
130
131 fn bare(&self) -> bool {
133 self.has_option("bare")
134 }
135
136 fn user_agent(&self) -> Option<String> {
138 self.get_option("user-agent")
139 }
140
141 fn passive(&self) -> Option<bool> {
143 if self.has_option("passive") || self.has_option("pasv") {
144 Some(true)
145 } else if self.has_option("active") || self.has_option("nopasv") {
146 Some(false)
147 } else {
148 None
149 }
150 }
151
152 fn unzipoptions(&self) -> Option<String> {
154 self.get_option("unzipopt")
155 }
156
157 fn dversionmangle(&self) -> Option<String> {
159 self.get_option("dversionmangle")
160 }
161
162 fn uversionmangle(&self) -> Option<String> {
164 self.get_option("uversionmangle")
165 }
166
167 fn downloadurlmangle(&self) -> Option<String> {
169 self.get_option("downloadurlmangle")
170 }
171
172 fn filenamemangle(&self) -> Option<String> {
174 self.get_option("filenamemangle")
175 }
176
177 fn pgpsigurlmangle(&self) -> Option<String> {
179 self.get_option("pgpsigurlmangle")
180 }
181
182 fn oversionmangle(&self) -> Option<String> {
184 self.get_option("oversionmangle")
185 }
186
187 fn pagemangle(&self) -> Option<String> {
189 self.get_option("pagemangle")
190 }
191
192 fn dirversionmangle(&self) -> Option<String> {
194 self.get_option("dirversionmangle")
195 }
196
197 fn versionmangle(&self) -> Option<String> {
199 self.get_option("versionmangle")
200 }
201
202 fn hrefdecode(&self) -> Option<bool> {
204 self.get_option("hrefdecode")
205 .map(|s| s == "1" || s == "yes")
206 }
207
208 fn format_url(&self, package: impl FnOnce() -> String) -> Result<url::Url, url::ParseError> {
210 crate::parse::subst(self.url().as_str(), package).parse()
211 }
212}