grass/dev/public/
api.rs

1use std::fmt::Display;
2
3use crate::dev::strategy::alias::{Alias, ResolveAliasResult};
4
5/// A string which represents a category.
6///
7/// This is a unique type, because not all conversion to a String make sense.
8/// For example, take `Alias`[^alias].
9/// If this were converted to a [std::str],
10/// then something like "{alias} -> {category}" would make more sense.
11/// But when used as a category, just the category should be used.
12///
13/// [^alias]: [crate::dev::strategy::alias::Alias]
14#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Default)]
15pub struct Category(pub String);
16
17#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Default)]
18pub struct RepositoryLocation {
19    pub category: Category,
20    pub repository: String,
21}
22
23impl RepositoryLocation {
24    pub fn to_session_string(&self) -> String {
25        format!("{}", self)
26    }
27}
28
29impl Display for RepositoryLocation {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        write!(f, "{}@{}", self.repository, self.category)
32    }
33}
34
35impl From<String> for Category {
36    fn from(value: String) -> Self {
37        Category(value)
38    }
39}
40
41impl From<&String> for Category {
42    fn from(value: &String) -> Self {
43        Category(value.clone())
44    }
45}
46
47impl From<&str> for Category {
48    fn from(value: &str) -> Self {
49        Category(value.to_owned())
50    }
51}
52
53impl From<Box<str>> for Category {
54    fn from(value: Box<str>) -> Self {
55        Category(String::from(value))
56    }
57}
58
59impl From<Alias> for Category {
60    fn from(value: Alias) -> Self {
61        value.category
62    }
63}
64
65impl From<ResolveAliasResult> for Category {
66    fn from(value: ResolveAliasResult) -> Self {
67        match value {
68            ResolveAliasResult::Alias(Alias { category, .. }) => category,
69            ResolveAliasResult::NoAlias(category) => Category(category),
70        }
71    }
72}
73
74impl AsRef<String> for Category {
75    fn as_ref(&self) -> &String {
76        &self.0
77    }
78}
79
80impl AsRef<str> for Category {
81    fn as_ref(&self) -> &str {
82        &self.0
83    }
84}
85
86impl<T, U> From<(T, U)> for RepositoryLocation
87where
88    T: Into<Category>,
89    U: Into<String>,
90{
91    fn from((category, repository): (T, U)) -> Self {
92        Self {
93            category: category.into(),
94            repository: repository.into(),
95        }
96    }
97}
98
99impl<T, U> From<&(T, U)> for RepositoryLocation
100where
101    T: Into<Category> + Clone,
102    U: Into<String> + Clone,
103{
104    fn from((category, repository): &(T, U)) -> Self {
105        Self {
106            category: category.clone().into(),
107            repository: repository.clone().into(),
108        }
109    }
110}
111
112impl RepositoryLocation {
113    pub fn new<T, U>(category: T, repository: U) -> Self
114    where
115        T: Into<Category>,
116        U: Into<String>,
117    {
118        RepositoryLocation {
119            category: category.into(),
120            repository: repository.into(),
121        }
122    }
123}
124
125impl Display for Category {
126    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127        self.0.fmt(f)
128    }
129}