cgroups_rs/systemd/
utils.rs1use crate::systemd::error::{Error, Result};
7use crate::systemd::{SCOPE_SUFFIX, SLICE_SUFFIX};
8
9pub fn is_slice_unit(name: &str) -> bool {
11 name.ends_with(SLICE_SUFFIX)
12}
13
14pub fn is_scope_unit(name: &str) -> bool {
16 name.ends_with(SCOPE_SUFFIX)
17}
18
19pub fn expand_slice(slice: &str) -> Result<String> {
32 if !slice.ends_with(SLICE_SUFFIX) || slice.len() < SLICE_SUFFIX.len() {
34 return Err(Error::InvalidArgument);
35 }
36
37 if slice.contains('/') {
39 return Err(Error::InvalidArgument);
40 }
41
42 let name = slice.trim_end_matches(SLICE_SUFFIX);
43
44 if name == "-" {
46 return Ok("".to_string());
47 }
48
49 let mut slice_path = String::new();
50 let mut prefix = String::new();
51 for sub_slice in name.split('-') {
52 if sub_slice.is_empty() {
53 return Err(Error::InvalidArgument);
54 }
55
56 slice_path = format!("{}/{}{}{}", slice_path, prefix, sub_slice, SLICE_SUFFIX);
57 prefix = format!("{}{}-", prefix, sub_slice);
58 }
59
60 slice_path.remove(0);
62
63 Ok(slice_path)
64}
65
66#[cfg(test)]
67mod tests {
68 use crate::systemd::utils::*;
69
70 #[test]
71 fn test_is_slice_unit() {
72 assert!(is_slice_unit("test.slice"));
73 assert!(!is_slice_unit("test.scope"));
74 }
75
76 #[test]
77 fn test_is_scope_unit() {
78 assert!(is_scope_unit("test.scope"));
79 assert!(!is_scope_unit("test.slice"));
80 }
81
82 #[test]
83 fn test_expand_slice() {
84 assert_eq!(expand_slice("test.slice").unwrap(), "test.slice");
85 assert_eq!(
86 expand_slice("test-1.slice").unwrap(),
87 "test.slice/test-1.slice"
88 );
89 assert_eq!(
90 expand_slice("test-1-test-2.slice").unwrap(),
91 "test.slice/test-1.slice/test-1-test.slice/test-1-test-2.slice"
92 );
93 assert_eq!(
94 expand_slice("slice-slice.slice").unwrap(),
95 "slice.slice/slice-slice.slice"
96 );
97 assert_eq!(expand_slice("-.slice").unwrap(), "");
98 assert!(expand_slice("invalid/slice").is_err());
99 assert!(expand_slice("invalid-slice").is_err());
100 }
101}