arch_pkg_text/value/dependency_name.rs
1use super::DependencyName;
2
3impl<'a> DependencyName<'a> {
4 /// Extract a valid dependency name from an input string.
5 ///
6 /// > Package names should only consist of lowercase alphanumerics and
7 /// > the following characters: `@._+-` (at symbol, dot, underscore, plus, hyphen).
8 /// > Names are not allowed to start with hyphens or dots.
9 /// >
10 /// > -- from <https://wiki.archlinux.org/title/PKGBUILD#pkgname>
11 ///
12 /// ```
13 /// # use arch_pkg_text::value::DependencyName;
14 /// # use pretty_assertions::assert_eq;
15 /// let (name, rest) = DependencyName::parse("rustup>=1.27.0-1");
16 /// assert_eq!(name, DependencyName("rustup"));
17 /// assert_eq!(rest, ">=1.27.0-1");
18 /// ```
19 pub fn parse(input: &'a str) -> (Self, &'a str) {
20 let stop = input
21 .char_indices()
22 .find(|&(index, char)| !DependencyName::is_valid_char(index, char));
23
24 let Some((stop_index, _)) = stop else {
25 return (DependencyName(input), "");
26 };
27
28 let content = &input[..stop_index];
29 let rest = &input[stop_index..];
30 (DependencyName(content), rest)
31 }
32
33 /// Check if a character belongs to a dependency name.
34 fn is_valid_char(index: usize, char: char) -> bool {
35 match (index, char) {
36 // lowercase alphanumeric is always valid
37 (_, 'a'..='z' | '0'..='9') => true,
38
39 // hyphen and dot are forbidden as first character
40 (0, '-' | '.') => false,
41
42 // some special characters are allowed as non-first character
43 (_, '@' | '.' | '_' | '+' | '-') => true,
44
45 // otherwise, invalid
46 (_, _) => false,
47 }
48 }
49}