blob: d96d4f9391d8776b28e97b217e921c98c9dcf0bc [file] [log] [blame]
Mårten Kongstad00cf0452023-05-26 16:48:01 +02001/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mårten Kongstad066575b2023-06-07 16:29:25 +020017use anyhow::{ensure, Result};
18
Mårten Kongstadfbd71e22023-05-31 13:29:35 +020019pub fn is_valid_name_ident(s: &str) -> bool {
Mårten Kongstadd18c9782023-06-13 13:30:58 +020020 // Identifiers must match [a-z][a-z0-9_]*, except consecutive underscores are not allowed
21 if s.contains("__") {
22 return false;
23 }
Mårten Kongstad00cf0452023-05-26 16:48:01 +020024 let mut chars = s.chars();
25 let Some(first) = chars.next() else {
26 return false;
27 };
28 if !first.is_ascii_lowercase() {
29 return false;
30 }
31 chars.all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '_')
32}
33
Mårten Kongstadfbd71e22023-05-31 13:29:35 +020034pub fn is_valid_package_ident(s: &str) -> bool {
35 s.split('.').all(is_valid_name_ident)
36}
37
Mårten Kongstad066575b2023-06-07 16:29:25 +020038pub fn create_device_config_ident(package: &str, flag_name: &str) -> Result<String> {
39 ensure!(is_valid_package_ident(package), "bad package");
40 ensure!(is_valid_package_ident(flag_name), "bad flag name");
41 Ok(format!("{}.{}", package, flag_name))
42}
43
Mårten Kongstad00cf0452023-05-26 16:48:01 +020044#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
Mårten Kongstadfbd71e22023-05-31 13:29:35 +020049 fn test_is_valid_name_ident() {
50 assert!(is_valid_name_ident("foo"));
51 assert!(is_valid_name_ident("foo_bar_123"));
Mårten Kongstadd18c9782023-06-13 13:30:58 +020052 assert!(is_valid_name_ident("foo_"));
Mårten Kongstad00cf0452023-05-26 16:48:01 +020053
Mårten Kongstadfbd71e22023-05-31 13:29:35 +020054 assert!(!is_valid_name_ident(""));
55 assert!(!is_valid_name_ident("123_foo"));
56 assert!(!is_valid_name_ident("foo-bar"));
57 assert!(!is_valid_name_ident("foo-b\u{00e5}r"));
Mårten Kongstadd18c9782023-06-13 13:30:58 +020058 assert!(!is_valid_name_ident("foo__bar"));
59 assert!(!is_valid_name_ident("_foo"));
Mårten Kongstadfbd71e22023-05-31 13:29:35 +020060 }
61
62 #[test]
63 fn test_is_valid_package_ident() {
64 assert!(is_valid_package_ident("foo"));
65 assert!(is_valid_package_ident("foo_bar_123"));
66 assert!(is_valid_package_ident("foo.bar"));
67 assert!(is_valid_package_ident("foo.bar.a123"));
Mårten Kongstadd18c9782023-06-13 13:30:58 +020068 assert!(!is_valid_package_ident("foo._bar"));
Mårten Kongstadfbd71e22023-05-31 13:29:35 +020069
70 assert!(!is_valid_package_ident(""));
71 assert!(!is_valid_package_ident("123_foo"));
72 assert!(!is_valid_package_ident("foo-bar"));
73 assert!(!is_valid_package_ident("foo-b\u{00e5}r"));
74 assert!(!is_valid_package_ident("foo.bar.123"));
75 assert!(!is_valid_package_ident(".foo.bar"));
76 assert!(!is_valid_package_ident("foo.bar."));
77 assert!(!is_valid_package_ident("."));
78 assert!(!is_valid_package_ident("foo..bar"));
Mårten Kongstadd18c9782023-06-13 13:30:58 +020079 assert!(!is_valid_package_ident("foo.__bar"));
Mårten Kongstad00cf0452023-05-26 16:48:01 +020080 }
Mårten Kongstad066575b2023-06-07 16:29:25 +020081
82 #[test]
83 fn test_create_device_config_ident() {
84 assert_eq!(
85 "com.foo.bar.some_flag",
86 create_device_config_ident("com.foo.bar", "some_flag").unwrap()
87 );
88 }
Mårten Kongstad00cf0452023-05-26 16:48:01 +020089}