rsass/sass/
name.rs

1use std::borrow::Cow;
2use std::fmt;
3
4/// A sass name, used to idenify functions, variables, mixins, etc.
5///
6/// A `-` and a `_` is considered equal in a name, both represented by a `_`.
7///
8/// # Examples
9/// ```
10/// # use rsass::sass::Name;
11/// assert_eq!(Name::from("foo-bar"), Name::from("foo_bar"));
12/// assert_eq!(Name::from_static("foo_bar"), Name::from("foo-bar"));
13/// ```
14#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
15pub struct Name {
16    key: Cow<'static, str>,
17}
18
19impl Name {
20    /// Key must not contain `-`.
21    ///
22    /// This function panics in debug mode if the key contains `-`.
23    pub fn from_static(key: &'static str) -> Self {
24        debug_assert!(!key.contains('-'));
25        Self { key: key.into() }
26    }
27
28    /// Check if a name is "module.local".
29    ///
30    /// If so, return the module name and the local name as separate names.
31    pub fn split_module(&self) -> Option<(String, Self)> {
32        self.key.split_once('.').map(|(module, local)| {
33            (
34                module.replace('_', "-").to_string(),
35                Self {
36                    key: local.to_string().into(),
37                },
38            )
39        })
40    }
41}
42
43impl fmt::Display for Name {
44    fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
45        self.key.replace('_', "-").fmt(out)
46    }
47}
48
49impl AsRef<str> for Name {
50    fn as_ref(&self) -> &str {
51        self.key.as_ref()
52    }
53}
54
55impl From<String> for Name {
56    fn from(key: String) -> Self {
57        if key.contains('-') {
58            Self {
59                key: key.replace('-', "_").into(),
60            }
61        } else {
62            Self { key: key.into() }
63        }
64    }
65}
66
67impl From<&str> for Name {
68    fn from(key: &str) -> Self {
69        Self {
70            key: key.replace('-', "_").into(),
71        }
72    }
73}
74impl From<&String> for Name {
75    fn from(key: &String) -> Self {
76        let key: &str = key.as_ref();
77        key.into()
78    }
79}
80
81#[test]
82fn test() {
83    assert_eq!(Name::from_static("foo_bar"), "foo_bar".into());
84    assert_eq!(Name::from_static("foo_bar"), "foo-bar".into());
85    assert_eq!(Name::from_static("foo_bar"), "foo_bar".to_string().into());
86    assert_eq!(Name::from_static("foo_bar"), "foo-bar".to_string().into());
87}