rustfmt_nightly/config/
macro_names.rs

1//! This module contains types and functions to support formatting specific macros.
2
3use itertools::Itertools;
4use std::{fmt, str};
5
6use serde::{Deserialize, Deserializer, Serialize};
7use serde_json as json;
8use thiserror::Error;
9
10/// Defines the name of a macro.
11#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
12pub struct MacroName(String);
13
14impl MacroName {
15    pub fn new(other: String) -> Self {
16        Self(other)
17    }
18}
19
20impl fmt::Display for MacroName {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        self.0.fmt(f)
23    }
24}
25
26impl From<MacroName> for String {
27    fn from(other: MacroName) -> Self {
28        other.0
29    }
30}
31
32/// Defines a selector to match against a macro.
33#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize)]
34pub enum MacroSelector {
35    Name(MacroName),
36    All,
37}
38
39impl<'de> Deserialize<'de> for MacroSelector {
40    fn deserialize<D>(de: D) -> Result<Self, D::Error>
41    where
42        D: Deserializer<'de>,
43    {
44        let s = String::deserialize(de)?;
45        std::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
46    }
47}
48
49impl fmt::Display for MacroSelector {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        match self {
52            Self::Name(name) => name.fmt(f),
53            Self::All => write!(f, "*"),
54        }
55    }
56}
57
58impl str::FromStr for MacroSelector {
59    type Err = std::convert::Infallible;
60
61    fn from_str(s: &str) -> Result<Self, Self::Err> {
62        Ok(match s {
63            "*" => MacroSelector::All,
64            name => MacroSelector::Name(MacroName(name.to_owned())),
65        })
66    }
67}
68
69/// A set of macro selectors.
70#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
71pub struct MacroSelectors(pub Vec<MacroSelector>);
72
73impl fmt::Display for MacroSelectors {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        write!(f, "{}", self.0.iter().format(", "))
76    }
77}
78
79#[derive(Error, Debug)]
80pub enum MacroSelectorsError {
81    #[error("{0}")]
82    Json(json::Error),
83}
84
85// This impl is needed for `Config::override_value` to work for use in tests.
86impl str::FromStr for MacroSelectors {
87    type Err = MacroSelectorsError;
88
89    fn from_str(s: &str) -> Result<Self, Self::Err> {
90        let raw: Vec<&str> = json::from_str(s).map_err(MacroSelectorsError::Json)?;
91        Ok(Self(
92            raw.into_iter()
93                .map(|raw| {
94                    MacroSelector::from_str(raw).expect("MacroSelector from_str is infallible")
95                })
96                .collect(),
97        ))
98    }
99}
100
101#[cfg(test)]
102mod test {
103    use super::*;
104    use std::str::FromStr;
105
106    #[test]
107    fn macro_names_from_str() {
108        let macro_names = MacroSelectors::from_str(r#"["foo", "*", "bar"]"#).unwrap();
109        assert_eq!(
110            macro_names,
111            MacroSelectors(
112                [
113                    MacroSelector::Name(MacroName("foo".to_owned())),
114                    MacroSelector::All,
115                    MacroSelector::Name(MacroName("bar".to_owned()))
116                ]
117                .into_iter()
118                .collect()
119            )
120        );
121    }
122
123    #[test]
124    fn macro_names_display() {
125        let macro_names = MacroSelectors::from_str(r#"["foo", "*", "bar"]"#).unwrap();
126        assert_eq!(format!("{macro_names}"), "foo, *, bar");
127    }
128}