infotheory/backends/
mod.rs1pub mod calibration;
10pub mod ctw;
11pub mod llm_policy;
13#[cfg(feature = "backend-mamba")]
15pub mod mambazip;
16pub mod match_model;
18pub mod particle;
20pub mod ppmd;
22pub mod rosaplus;
23#[cfg(feature = "backend-rwkv")]
25pub mod rwkvzip;
26pub mod sequitur;
28pub mod sparse_match;
30pub mod text_context;
32pub mod zpaq_rate;
33use crate::coders::CoderType;
34
35#[derive(Clone, Copy, Debug, Eq, PartialEq)]
37pub enum BackendAvailability {
38 Enabled(&'static str),
40 Disabled {
42 canonical: &'static str,
44 feature: &'static str,
46 },
47}
48
49pub const AVAILABLE_RATE_BACKENDS: &[&str] = &[
51 "rosaplus",
52 "ctw",
53 "fac-ctw",
54 "match",
55 "sparse-match",
56 "ppmd",
57 "sequitur",
58 "calibrated",
59 #[cfg(feature = "backend-mamba")]
60 "mamba",
61 #[cfg(feature = "backend-rwkv")]
62 "rwkv7",
63 #[cfg(feature = "backend-zpaq")]
64 "zpaq",
65 "mixture",
66 "particle",
67];
68
69pub const AVAILABLE_COMPRESSION_BACKENDS: &[&str] = &[
71 #[cfg(feature = "backend-zpaq")]
72 "zpaq",
73 "rate-ac",
74 "rate-rans",
75 #[cfg(feature = "backend-rwkv")]
76 "rwkv7",
77];
78
79pub fn resolve_rate_backend_name(input: &str) -> Option<BackendAvailability> {
84 let key = input.trim().to_ascii_lowercase();
85 match key.as_str() {
86 "rosaplus" | "rosa" => Some(BackendAvailability::Enabled("rosaplus")),
87 "ctw" => Some(BackendAvailability::Enabled("ctw")),
88 "fac-ctw" | "facctw" => Some(BackendAvailability::Enabled("fac-ctw")),
89 "match" => Some(BackendAvailability::Enabled("match")),
90 "sparse-match" | "sparse_match" | "sparsematch" => {
91 Some(BackendAvailability::Enabled("sparse-match"))
92 }
93 "ppmd" | "ppm" => Some(BackendAvailability::Enabled("ppmd")),
94 "sequitur" => Some(BackendAvailability::Enabled("sequitur")),
95 "calibrated" | "cal" => Some(BackendAvailability::Enabled("calibrated")),
96 "zpaq" => {
97 if cfg!(feature = "backend-zpaq") {
98 Some(BackendAvailability::Enabled("zpaq"))
99 } else {
100 Some(BackendAvailability::Disabled {
101 canonical: "zpaq",
102 feature: "backend-zpaq",
103 })
104 }
105 }
106 "mixture" | "mix" => Some(BackendAvailability::Enabled("mixture")),
107 "particle" | "particles" => Some(BackendAvailability::Enabled("particle")),
108 "mamba" | "mamba1" => {
109 if cfg!(feature = "backend-mamba") {
110 Some(BackendAvailability::Enabled("mamba"))
111 } else {
112 Some(BackendAvailability::Disabled {
113 canonical: "mamba",
114 feature: "backend-mamba",
115 })
116 }
117 }
118 "rwkv7" | "rwkv" => {
119 if cfg!(feature = "backend-rwkv") {
120 Some(BackendAvailability::Enabled("rwkv7"))
121 } else {
122 Some(BackendAvailability::Disabled {
123 canonical: "rwkv7",
124 feature: "backend-rwkv",
125 })
126 }
127 }
128 _ => None,
129 }
130}
131
132pub fn resolve_compression_backend_name(input: &str) -> Option<BackendAvailability> {
137 let key = input.trim().to_ascii_lowercase();
138 match key.as_str() {
139 "zpaq" => {
140 if cfg!(feature = "backend-zpaq") {
141 Some(BackendAvailability::Enabled("zpaq"))
142 } else {
143 Some(BackendAvailability::Disabled {
144 canonical: "zpaq",
145 feature: "backend-zpaq",
146 })
147 }
148 }
149 "rwkv7" | "rwkv" => {
150 if cfg!(feature = "backend-rwkv") {
151 Some(BackendAvailability::Enabled("rwkv7"))
152 } else {
153 Some(BackendAvailability::Disabled {
154 canonical: "rwkv7",
155 feature: "backend-rwkv",
156 })
157 }
158 }
159 "rate-ac" | "rate_ac" | "rateac" => Some(BackendAvailability::Enabled("rate-ac")),
160 "rate-rans" | "rate_rans" | "raterans" => Some(BackendAvailability::Enabled("rate-rans")),
161 _ => None,
162 }
163}
164
165pub fn parse_rate_coder(v: &str) -> Option<CoderType> {
167 match v {
168 "ac" | "AC" => Some(CoderType::AC),
169 "rans" | "RANS" | "rANS" => Some(CoderType::RANS),
170 _ => None,
171 }
172}
173
174#[cfg(feature = "backend-rwkv")]
176pub fn parse_rwkv7_coder(v: &str) -> Option<CoderType> {
177 parse_rate_coder(v)
178}
179
180#[cfg(test)]
181mod tests {
182 use super::*;
183
184 #[test]
185 fn resolve_rate_backend_name_canonicalizes_aliases() {
186 assert_eq!(
187 resolve_rate_backend_name(" Rosa "),
188 Some(BackendAvailability::Enabled("rosaplus"))
189 );
190 assert_eq!(
191 resolve_rate_backend_name("facctw"),
192 Some(BackendAvailability::Enabled("fac-ctw"))
193 );
194 assert_eq!(
195 resolve_rate_backend_name("mix"),
196 Some(BackendAvailability::Enabled("mixture"))
197 );
198 assert_eq!(
199 resolve_rate_backend_name("sequitur"),
200 Some(BackendAvailability::Enabled("sequitur"))
201 );
202 assert_eq!(resolve_rate_backend_name("unknown"), None);
203 }
204
205 #[test]
206 fn resolve_rate_backend_name_reports_feature_disabled() {
207 if cfg!(feature = "backend-zpaq") {
208 assert_eq!(
209 resolve_rate_backend_name("zpaq"),
210 Some(BackendAvailability::Enabled("zpaq"))
211 );
212 } else {
213 assert_eq!(
214 resolve_rate_backend_name("zpaq"),
215 Some(BackendAvailability::Disabled {
216 canonical: "zpaq",
217 feature: "backend-zpaq",
218 })
219 );
220 }
221
222 if cfg!(feature = "backend-rwkv") {
223 assert_eq!(
224 resolve_rate_backend_name("rwkv7"),
225 Some(BackendAvailability::Enabled("rwkv7"))
226 );
227 } else {
228 assert_eq!(
229 resolve_rate_backend_name("rwkv"),
230 Some(BackendAvailability::Disabled {
231 canonical: "rwkv7",
232 feature: "backend-rwkv",
233 })
234 );
235 }
236
237 if cfg!(feature = "backend-mamba") {
238 assert_eq!(
239 resolve_rate_backend_name("mamba1"),
240 Some(BackendAvailability::Enabled("mamba"))
241 );
242 } else {
243 assert_eq!(
244 resolve_rate_backend_name("mamba"),
245 Some(BackendAvailability::Disabled {
246 canonical: "mamba",
247 feature: "backend-mamba",
248 })
249 );
250 }
251 }
252
253 #[test]
254 fn resolve_compression_backend_name_canonicalizes_aliases() {
255 assert_eq!(resolve_compression_backend_name("unknown"), None);
256
257 if cfg!(feature = "backend-zpaq") {
258 assert_eq!(
259 resolve_compression_backend_name("zpaq"),
260 Some(BackendAvailability::Enabled("zpaq"))
261 );
262 } else {
263 assert_eq!(
264 resolve_compression_backend_name("zpaq"),
265 Some(BackendAvailability::Disabled {
266 canonical: "zpaq",
267 feature: "backend-zpaq",
268 })
269 );
270 }
271
272 assert_eq!(
273 resolve_compression_backend_name("rate_ac"),
274 Some(BackendAvailability::Enabled("rate-ac"))
275 );
276 assert_eq!(
277 resolve_compression_backend_name("raterans"),
278 Some(BackendAvailability::Enabled("rate-rans"))
279 );
280
281 if cfg!(feature = "backend-rwkv") {
282 assert_eq!(
283 resolve_compression_backend_name("rwkv"),
284 Some(BackendAvailability::Enabled("rwkv7"))
285 );
286 }
287 }
288
289 #[cfg(feature = "backend-rwkv")]
290 #[test]
291 fn parse_rwkv7_coder_accepts_common_aliases() {
292 assert_eq!(parse_rwkv7_coder("ac"), Some(CoderType::AC));
293 assert_eq!(parse_rwkv7_coder("AC"), Some(CoderType::AC));
294 assert_eq!(parse_rwkv7_coder("rans"), Some(CoderType::RANS));
295 assert_eq!(parse_rwkv7_coder("RANS"), Some(CoderType::RANS));
296 assert_eq!(parse_rwkv7_coder("nope"), None);
297 }
298}