changepacks_utils/
split_version.rs1use anyhow::Result;
2
3pub fn split_version(version: &str) -> Result<(Option<String>, String)> {
8 let first_digit_pos = version
9 .char_indices()
10 .find(|(_, c)| c.is_ascii_digit())
11 .map(|(pos, _)| pos);
12
13 match first_digit_pos {
14 Some(0) | None => Ok((None, version.to_string())),
15 Some(pos) => {
16 let prefix = version[..pos].to_string();
17 let version_part = version[pos..].to_string();
18 Ok((Some(prefix), version_part))
19 }
20 }
21}
22
23#[cfg(test)]
24mod tests {
25 use super::*;
26
27 use rstest::rstest;
28
29 #[rstest]
30 #[case("1.0.0", (None, "1.0.0"))]
31 #[case("^1.0.0", (Some("^"), "1.0.0"))]
32 #[case("~1.0.0", (Some("~"), "1.0.0"))]
33 #[case("1.0.0-alpha.1", (None, "1.0.0-alpha.1"))]
34 #[case("1.0.0-alpha.1+build1", (None, "1.0.0-alpha.1+build1"))]
35 #[case(">=1.0.0+build1", (Some(">="), "1.0.0+build1"))]
36 #[case("helloworld-1.0.2", (Some("helloworld-"), "1.0.2"))]
37 #[case("latest", (None, "latest"))]
38 #[case("*", (None, "*"))]
39 fn test_split_version(#[case] input: &str, #[case] expected: (Option<&str>, &str)) {
40 let (prefix, version) = split_version(input).unwrap();
41 assert_eq!(prefix.as_deref(), expected.0);
42 assert_eq!(version.as_str(), expected.1);
43 }
44}