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}