alpm_utils/
target.rs

1use std::fmt;
2
3/// Trait for being generic over Target and Targ
4pub trait AsTarg {
5    /// Converts to a targ.
6    fn as_targ(&self) -> Targ;
7}
8
9impl<T> AsTarg for T
10where
11    T: AsRef<str>,
12{
13    fn as_targ(&self) -> Targ {
14        Targ::from(self.as_ref())
15    }
16}
17
18/// A packge to find, optionally from a specific repository.
19#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
20pub struct Target {
21    /// The repository the package should come from. None for any repository.
22    pub repo: Option<String>,
23    /// The name of the package, may also contain a version constraint.
24    pub pkg: String,
25}
26
27impl AsTarg for Target {
28    fn as_targ(&self) -> Targ {
29        Targ::new(self.repo.as_deref(), &self.pkg)
30    }
31}
32
33impl Target {
34    /// Create a new Target.
35    pub fn new<S: Into<String>>(repo: Option<S>, pkg: S) -> Target {
36        Target {
37            repo: repo.map(Into::into),
38            pkg: pkg.into(),
39        }
40    }
41}
42
43/// A packge to find, optionally from a specific repository.
44#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
45pub struct Targ<'a> {
46    /// The repository the package should come from. None for any repository.
47    pub repo: Option<&'a str>,
48    /// The name of the package, may also contain a version constraint.
49    pub pkg: &'a str,
50}
51
52impl<'a> Targ<'a> {
53    /// Create a new Targ.
54    pub fn new(repo: Option<&'a str>, pkg: &'a str) -> Targ<'a> {
55        Targ { repo, pkg }
56    }
57}
58
59impl<'a> AsTarg for Targ<'a> {
60    fn as_targ(&self) -> Targ {
61        *self
62    }
63}
64
65impl<'a, S: AsRef<str> + ?Sized> From<&'a S> for Targ<'a> {
66    fn from(s: &'a S) -> Self {
67        let mut split = s.as_ref().split('/');
68        let first = split.next().unwrap();
69        let repo;
70        let pkg;
71
72        if let Some(p) = split.next() {
73            repo = Some(first);
74            pkg = p;
75        } else {
76            repo = None;
77            pkg = first;
78        }
79
80        Targ { repo, pkg }
81    }
82}
83
84impl<'a> fmt::Display for Targ<'a> {
85    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
86        if let Some(repo) = self.repo {
87            write!(fmt, "{}/{}", repo, self.pkg)
88        } else {
89            write!(fmt, "{}", self.pkg)
90        }
91    }
92}
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97
98    #[test]
99    fn test_target() {
100        let pkg = "repo/pkg";
101        let pkg2 = String::from("pkg2");
102
103        let target = Targ::from(pkg);
104        let target2 = Targ::from(pkg2.as_str());
105
106        assert_eq!(target.repo, Some("repo"));
107        assert_eq!(target.pkg, "pkg");
108        assert_eq!(target2.repo, None);
109        assert_eq!(target2.pkg, "pkg2");
110    }
111}