educe/
panic.rs

1use core::fmt::{self, Display, Formatter};
2
3use proc_macro2::Span;
4use syn::{spanned::Spanned, Ident, Path, Variant};
5
6use crate::{common::path::path_to_string, Trait};
7
8struct DisplayStringSlice<'a>(&'a [&'static str]);
9
10impl<'a> Display for DisplayStringSlice<'a> {
11    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
12        if !self.0.is_empty() {
13            f.write_str(", which should be reformatted as follows:")?;
14
15            for &s in self.0 {
16                f.write_str("\n    ")?;
17                f.write_str(s)?;
18            }
19        }
20
21        Ok(())
22    }
23}
24
25struct DisplayTraits;
26
27impl Display for DisplayTraits {
28    #[inline]
29    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
30        for t in &Trait::VARIANTS[..Trait::VARIANTS.len() - 1] {
31            f.write_str("\n    ")?;
32            f.write_fmt(format_args!("{t:?}"))?;
33        }
34
35        Ok(())
36    }
37}
38
39#[inline]
40pub(crate) fn derive_attribute_not_set_up_yet() -> syn::Error {
41    syn::Error::new(
42        Span::call_site(),
43        "you are using `Educe` in the `derive` attribute, but it has not been set up yet",
44    )
45}
46
47#[inline]
48pub(crate) fn attribute_incorrect_place(name: &Ident) -> syn::Error {
49    syn::Error::new(name.span(), format!("the `{name}` attribute cannot be placed here"))
50}
51
52#[inline]
53pub(crate) fn attribute_incorrect_format_with_span(
54    name: &Ident,
55    span: Span,
56    correct_usage: &[&'static str],
57) -> syn::Error {
58    if correct_usage.is_empty() {
59        attribute_incorrect_place(name)
60    } else {
61        syn::Error::new(
62            span,
63            format!(
64                "you are using an incorrect format of the `{name}` attribute{}",
65                DisplayStringSlice(correct_usage)
66            ),
67        )
68    }
69}
70
71#[inline]
72pub(crate) fn attribute_incorrect_format(
73    name: &Ident,
74    correct_usage: &[&'static str],
75) -> syn::Error {
76    attribute_incorrect_format_with_span(name, name.span(), correct_usage)
77}
78
79#[inline]
80pub(crate) fn parameter_reset(name: &Ident) -> syn::Error {
81    syn::Error::new(name.span(), format!("you are trying to reset the `{name}` parameter"))
82}
83
84#[inline]
85pub(crate) fn educe_format_incorrect(name: &Ident) -> syn::Error {
86    attribute_incorrect_format(name, &[stringify!(#[educe(Trait1, Trait2, ..., TraitN)])])
87}
88
89#[inline]
90pub(crate) fn unsupported_trait(name: &Path) -> syn::Error {
91    let span = name.span();
92
93    match name.get_ident() {
94        Some(name) => syn::Error::new(
95            span,
96            format!("unsupported trait `{name}`, available traits:{DisplayTraits}"),
97        ),
98        None => {
99            let name = path_to_string(name);
100
101            syn::Error::new(
102                span,
103                format!("unsupported trait `{name}`, available traits:{DisplayTraits}"),
104            )
105        },
106    }
107}
108
109#[inline]
110pub(crate) fn reuse_a_trait(name: &Ident) -> syn::Error {
111    syn::Error::new(name.span(), format!("the trait `{name}` is used repeatedly"))
112}
113
114#[inline]
115pub(crate) fn trait_not_used(name: &Ident) -> syn::Error {
116    syn::Error::new(name.span(), format!("the trait `{name}` is not used"))
117}
118
119#[inline]
120pub(crate) fn trait_not_support_union(name: &Ident) -> syn::Error {
121    syn::Error::new(name.span(), format!("the trait `{name}` does not support to a union"))
122}
123
124#[inline]
125pub(crate) fn trait_not_support_unit_variant(name: &Ident, variant: &Variant) -> syn::Error {
126    syn::Error::new(
127        variant.span(),
128        format!("the trait `{name}` cannot be implemented for an enum which has unit variants"),
129    )
130}