1use rustc_ast::ast::Safety;
2use rustc_hir::AttrStyle;
3use rustc_span::Symbol;
4
5#[derive(#[automatically_derived]
impl ::core::clone::Clone for AttributeTemplate {
#[inline]
fn clone(&self) -> AttributeTemplate {
let _: ::core::clone::AssertParamIsClone<bool>;
let _:
::core::clone::AssertParamIsClone<Option<&'static [&'static str]>>;
let _: ::core::clone::AssertParamIsClone<&'static [Symbol]>;
let _:
::core::clone::AssertParamIsClone<Option<&'static [&'static str]>>;
let _: ::core::clone::AssertParamIsClone<Option<&'static str>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AttributeTemplate { }Copy, #[automatically_derived]
impl ::core::default::Default for AttributeTemplate {
#[inline]
fn default() -> AttributeTemplate {
AttributeTemplate {
word: ::core::default::Default::default(),
list: ::core::default::Default::default(),
one_of: ::core::default::Default::default(),
name_value_str: ::core::default::Default::default(),
docs: ::core::default::Default::default(),
}
}
}Default)]
8pub struct AttributeTemplate {
9 pub word: bool,
11 pub list: Option<&'static [&'static str]>,
13 pub one_of: &'static [Symbol],
16 pub name_value_str: Option<&'static [&'static str]>,
19 pub docs: Option<&'static str>,
21}
22
23pub enum AttrSuggestionStyle {
24 Attribute(AttrStyle),
27 EmbeddedAttribute,
30 Macro,
33}
34
35impl AttributeTemplate {
36 pub fn suggestions(
37 &self,
38 style: AttrSuggestionStyle,
39 safety: Safety,
40 name: impl std::fmt::Display,
41 ) -> Vec<String> {
42 let (start, macro_call, end) = match style {
43 AttrSuggestionStyle::Attribute(AttrStyle::Outer) => ("#[", "", "]"),
44 AttrSuggestionStyle::Attribute(AttrStyle::Inner) => ("#![", "", "]"),
45 AttrSuggestionStyle::Macro => ("", "!", ""),
46 AttrSuggestionStyle::EmbeddedAttribute => ("", "", ""),
47 };
48
49 let mut suggestions = ::alloc::vec::Vec::new()vec![];
50
51 let (safety_start, safety_end) = match safety {
52 Safety::Unsafe(_) => ("unsafe(", ")"),
53 _ => ("", ""),
54 };
55
56 if self.word {
57 if true {
if !macro_call.is_empty() {
{
::core::panicking::panic_fmt(format_args!("Macro suggestions use list style"));
}
};
};debug_assert!(macro_call.is_empty(), "Macro suggestions use list style");
58 suggestions.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}{2}{3}{4}", start,
safety_start, name, safety_end, end))
})format!("{start}{safety_start}{name}{safety_end}{end}"));
59 }
60 if let Some(descr) = self.list {
61 for descr in descr {
62 suggestions.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}{2}{3}({4}){5}{6}", start,
safety_start, name, macro_call, descr, safety_end, end))
})format!(
63 "{start}{safety_start}{name}{macro_call}({descr}){safety_end}{end}"
64 ));
65 }
66 }
67 suggestions.extend(
68 self.one_of
69 .iter()
70 .map(|&word| ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}{2}({3}){4}{5}", start,
safety_start, name, word, safety_end, end))
})format!("{start}{safety_start}{name}({word}){safety_end}{end}")),
71 );
72 if let Some(descr) = self.name_value_str {
73 if true {
if !macro_call.is_empty() {
{
::core::panicking::panic_fmt(format_args!("Macro suggestions use list style"));
}
};
};debug_assert!(macro_call.is_empty(), "Macro suggestions use list style");
74 for descr in descr {
75 suggestions
76 .push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}{2} = \"{3}\"{4}{5}", start,
safety_start, name, descr, safety_end, end))
})format!("{start}{safety_start}{name} = \"{descr}\"{safety_end}{end}"));
77 }
78 }
79 suggestions.sort();
80
81 suggestions
82 }
83}
84
85#[macro_export]
89macro_rules! template {
90 (Word) => { $crate::template!(@ true, None, &[], None, None) };
91 (Word, $link: literal) => { $crate::template!(@ true, None, &[], None, Some($link)) };
92 (List: $descr: expr) => { $crate::template!(@ false, Some($descr), &[], None, None) };
93 (List: $descr: expr, $link: literal) => { $crate::template!(@ false, Some($descr), &[], None, Some($link)) };
94 (OneOf: $one_of: expr) => { $crate::template!(@ false, None, $one_of, None, None) };
95 (NameValueStr: [$($descr: literal),* $(,)?]) => { $crate::template!(@ false, None, &[], Some(&[$($descr,)*]), None) };
96 (NameValueStr: [$($descr: literal),* $(,)?], $link: literal) => { $crate::template!(@ false, None, &[], Some(&[$($descr,)*]), Some($link)) };
97 (NameValueStr: $descr: literal) => { $crate::template!(@ false, None, &[], Some(&[$descr]), None) };
98 (NameValueStr: $descr: literal, $link: literal) => { $crate::template!(@ false, None, &[], Some(&[$descr]), Some($link)) };
99 (Word, List: $descr: expr) => { $crate::template!(@ true, Some($descr), &[], None, None) };
100 (Word, List: $descr: expr, $link: literal) => { $crate::template!(@ true, Some($descr), &[], None, Some($link)) };
101 (Word, NameValueStr: $descr: expr) => { $crate::template!(@ true, None, &[], Some(&[$descr]), None) };
102 (Word, NameValueStr: $descr: expr, $link: literal) => { $crate::template!(@ true, None, &[], Some(&[$descr]), Some($link)) };
103 (List: $descr1: expr, NameValueStr: $descr2: expr) => {
104 $crate::template!(@ false, Some($descr1), &[], Some(&[$descr2]), None)
105 };
106 (List: $descr1: expr, NameValueStr: $descr2: expr, $link: literal) => {
107 $crate::template!(@ false, Some($descr1), &[], Some(&[$descr2]), Some($link))
108 };
109 (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
110 $crate::template!(@ true, Some($descr1), &[], Some(&[$descr2]), None)
111 };
112 (Word, List: $descr1: expr, NameValueStr: $descr2: expr, $link: literal) => {
113 $crate::template!(@ true, Some($descr1), &[], Some(&[$descr2]), Some($link))
114 };
115 (@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr, $link: expr) => { $crate::AttributeTemplate {
116 word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str, docs: $link,
117 } };
118}