Skip to main content

mig_types/
paths.rs

1use std::path::{Path, PathBuf};
2
3/// Base directory for generated MIG schema files, relative to workspace root.
4const GENERATED_BASE: &str = "crates/mig-types/src/generated";
5
6/// Returns the directory containing PID schema JSON files for a given
7/// format version and message type.
8///
9/// Both arguments are lowercased automatically.
10///
11/// Example: `schema_dir("FV2504", "UTILMD")` -> `crates/mig-types/src/generated/fv2504/utilmd/pids`
12pub fn schema_dir(format_version: &str, message_type: &str) -> PathBuf {
13    Path::new(GENERATED_BASE)
14        .join(format_version.to_lowercase())
15        .join(message_type.to_lowercase())
16        .join("pids")
17}
18
19/// Returns the path to a specific PID schema JSON file.
20///
21/// Example: `pid_schema_file("FV2504", "UTILMD", "55001")` ->
22///   `crates/mig-types/src/generated/fv2504/utilmd/pids/pid_55001_schema.json`
23pub fn pid_schema_file(format_version: &str, message_type: &str, pid: &str) -> PathBuf {
24    schema_dir(format_version, message_type).join(format!("pid_{pid}_schema.json"))
25}
26
27/// Returns the base directory for all generated schemas.
28pub fn generated_base() -> &'static Path {
29    Path::new(GENERATED_BASE)
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn test_schema_dir() {
38        assert_eq!(
39            schema_dir("FV2504", "UTILMD"),
40            PathBuf::from("crates/mig-types/src/generated/fv2504/utilmd/pids")
41        );
42    }
43
44    #[test]
45    fn test_schema_dir_case_insensitive() {
46        assert_eq!(
47            schema_dir("fv2504", "utilmd"),
48            schema_dir("FV2504", "UTILMD")
49        );
50    }
51
52    #[test]
53    fn test_pid_schema_file() {
54        assert_eq!(
55            pid_schema_file("FV2504", "UTILMD", "55001"),
56            PathBuf::from(
57                "crates/mig-types/src/generated/fv2504/utilmd/pids/pid_55001_schema.json"
58            )
59        );
60    }
61
62    #[test]
63    fn test_generated_base() {
64        assert_eq!(
65            generated_base(),
66            Path::new("crates/mig-types/src/generated")
67        );
68    }
69}
70
71/// The PID a generated sample's file stem stands for: `55001` for `55001` and
72/// for its branch sample `55001__ZAP` (a sample of the same PID whose groups
73/// exclude the main sample's). `None` for a stem that names no PID
74/// (`##alt##`, `aperak`).
75pub fn sample_pid(stem: &str) -> Option<&str> {
76    let pid = stem.split("__").next()?;
77    (!pid.is_empty() && pid.chars().all(|c| c.is_ascii_digit())).then_some(pid)
78}
79
80#[cfg(test)]
81mod sample_pid_tests {
82    use super::sample_pid;
83
84    #[test]
85    fn a_branch_sample_names_its_pid() {
86        assert_eq!(sample_pid("55001"), Some("55001"));
87        assert_eq!(sample_pid("55001__ZAP"), Some("55001"));
88        assert_eq!(sample_pid("##alt##"), None);
89        assert_eq!(sample_pid("aperak"), None);
90    }
91}