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