Skip to main content

casc_lib/config/
cdn_config.rs

1//! Parser for CASC CDN configuration files.
2//!
3//! The CDN config is a `key = value` text file (with `#` comment lines) identified
4//! by the `cdn_key` hash from `.build.info`.
5//! It lists the archive hashes that make up the remote content store, an archive
6//! group hash, and a file index reference.
7
8use std::collections::HashMap;
9
10use crate::error::Result;
11
12/// Parsed CDN configuration from a CASC CDN config file.
13#[derive(Debug, Clone, Default)]
14pub struct CdnConfig {
15    /// Hex hashes of the remote data archives.
16    pub archives: Vec<String>,
17    /// Combined group hash for the archive set.
18    pub archive_group: String,
19    /// File index hash used for loose-file CDN lookups.
20    pub file_index: String,
21    /// Raw key-value store for all fields.
22    pub raw: HashMap<String, String>,
23}
24
25/// Parse a CASC CDN config (key = value format, `#` comments).
26pub fn parse_cdn_config(content: &str) -> Result<CdnConfig> {
27    let mut raw: HashMap<String, String> = HashMap::new();
28
29    for line in content.lines() {
30        let trimmed = line.trim();
31        if trimmed.is_empty() || trimmed.starts_with('#') {
32            continue;
33        }
34
35        if let Some((key, value)) = trimmed.split_once(" = ") {
36            raw.insert(key.to_string(), value.to_string());
37        }
38    }
39
40    let get = |key: &str| -> String { raw.get(key).cloned().unwrap_or_default() };
41
42    let archives_raw = get("archives");
43    let archives: Vec<String> = if archives_raw.is_empty() {
44        Vec::new()
45    } else {
46        archives_raw.split(' ').map(String::from).collect()
47    };
48
49    Ok(CdnConfig {
50        archives,
51        archive_group: get("archive-group"),
52        file_index: get("file-index"),
53        raw,
54    })
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn parse_archives() {
63        let data = "archives = abc123 def456 789abc\n";
64        let config = parse_cdn_config(data).unwrap();
65        assert_eq!(config.archives.len(), 3);
66        assert_eq!(config.archives[0], "abc123");
67    }
68
69    #[test]
70    fn parse_archive_group() {
71        let data = "archive-group = deadbeef\n";
72        let config = parse_cdn_config(data).unwrap();
73        assert_eq!(config.archive_group, "deadbeef");
74    }
75}