use proc_macro2::Span;
pub struct Error;
impl Error {
pub fn visited(span: Span) -> syn::Error {
syn::Error::new(
span,
"`#[derive_where(..)` was already applied to this item before, this occurs when using \
a qualified path for any `#[derive_where(..)`s except the first",
)
}
pub fn path_unnecessary(span: Span, default: &str) -> syn::Error {
syn::Error::new(
span,
format!(
"unnecessary path qualification, `{}` is used by default",
default
),
)
}
pub fn crate_(span: Span) -> syn::Error {
syn::Error::new(
span,
"the `crate` option has to be defined in it's own `#[derive_where(..)` attribute",
)
}
pub fn none(span: Span) -> syn::Error {
syn::Error::new(
span,
"no traits found to implement, use `#[derive_where(..)` to specify some",
)
}
pub fn empty(span: Span) -> syn::Error {
syn::Error::new(span, "empty `derive_where` found")
}
pub fn use_case(span: Span) -> syn::Error {
syn::Error::new(
span,
"this can be handled by standard `#[derive(..)]`, use a `skip` or `incomparable` \
attribute, implement `Default` on an enum, or different generic type parameters",
)
}
pub fn item_empty(span: Span) -> syn::Error {
syn::Error::new(
span,
"derive-where doesn't support empty items, as this can already be handled by standard \
`#[derive(..)]`",
)
}
pub fn union(span: Span) -> syn::Error {
syn::Error::new(
span,
"traits other then `Clone` and `Copy` aren't supported by unions",
)
}
#[cfg(feature = "zeroize")]
pub fn option_trait(span: Span, attribute: &str) -> syn::Error {
syn::Error::new(span, format!("`{}` doesn't support this option", attribute))
}
pub fn option(span: Span) -> syn::Error {
syn::Error::new(span, "unknown option")
}
pub fn options(span: Span, trait_: &str) -> syn::Error {
syn::Error::new(span, format!("`{}` doesn't support any options", trait_))
}
pub fn option_syntax(span: Span) -> syn::Error {
syn::Error::new(span, "unexpected option syntax")
}
pub fn option_empty(span: Span) -> syn::Error {
syn::Error::new(span, "empty attribute option found")
}
#[cfg(feature = "zeroize")]
pub fn option_required(span: Span, option: &str) -> syn::Error {
syn::Error::new(span, format!("`{}` requires an option", option))
}
pub fn option_duplicate(span: Span, option: &str) -> syn::Error {
syn::Error::new(span, format!("duplicate `{}` option", option))
}
pub fn option_enum_skip_inner(span: Span) -> syn::Error {
syn::Error::new(
span,
"enums don't support `skip_inner`, use it on a variant instead",
)
}
pub fn option_skip_inner(span: Span) -> syn::Error {
syn::Error::new(
span,
"unexpected `skip` on a field when parent already uses `skip_inner` with this trait",
)
}
pub fn option_skip_empty(span: Span) -> syn::Error {
syn::Error::new(span, "no fields to skip")
}
pub fn option_skip_all(span: Span) -> syn::Error {
syn::Error::new(
span,
"unexpected constraint on `skip` when unconstrained `skip` already used",
)
}
pub fn option_skip_duplicate(span: Span, trait_: &str) -> syn::Error {
syn::Error::new(span, format!("duplicate `{}` constraint on `skip`", trait_))
}
pub fn option_skip_no_trait(span: Span) -> syn::Error {
syn::Error::new(span, "no trait that can be skipped is being implemented")
}
pub fn option_skip_trait(span: Span) -> syn::Error {
syn::Error::new(span, "trait to be skipped isn't being implemented")
}
pub fn skip_group(span: Span) -> syn::Error {
syn::Error::new(
span,
format!(
"unsupported skip group, expected one of {}",
Self::skip_group_list()
),
)
}
pub fn path(span: Span, parse_error: syn::Error) -> syn::Error {
syn::Error::new(span, format!("expected path, {}", parse_error))
}
pub fn trait_(span: Span) -> syn::Error {
syn::Error::new(
span,
format!("unsupported trait, expected one of {}", Self::trait_list()),
)
}
pub fn trait_syntax(span: Span) -> syn::Error {
syn::Error::new(
span,
format!(
"unsupported trait syntax, expected one of {}",
Self::trait_list()
),
)
}
pub fn derive_where_delimiter(span: Span) -> syn::Error {
syn::Error::new(span, "expected `;` or `,")
}
pub fn generic(span: Span) -> syn::Error {
syn::Error::new(span, "only type predicates are supported")
}
pub fn generic_syntax(span: Span, parse_error: syn::Error) -> syn::Error {
syn::Error::new(span, format!("expected type to bind to, {}", parse_error))
}
pub fn trait_duplicate(span: Span) -> syn::Error {
syn::Error::new(span, "duplicate trait with the same bound")
}
pub fn default(span: Span) -> syn::Error {
syn::Error::new(
span,
"`default` is only supported if `Default` is being implemented",
)
}
pub fn default_missing(span: Span) -> syn::Error {
syn::Error::new(
span,
"required `default` option on a variant if `Default` is being implemented",
)
}
pub fn default_duplicate(span: Span) -> syn::Error {
syn::Error::new(span, "multiple `default` options in enum")
}
pub fn incomparable(span: Span) -> syn::Error {
syn::Error::new(
span,
"`incomparable` is only supported if `PartialEq` or `PartialOrd` is being implemented",
)
}
pub fn non_partial_incomparable(span: Span) -> syn::Error {
syn::Error::new(
span,
"`incomparable` is not supported if `Eq` or `Ord` is being implemented",
)
}
pub fn incomparable_on_item_and_variant(item: Span, variant: Span) -> syn::Error {
syn::Error::new(
item.join(variant).unwrap_or(item),
"`incomparable` cannot be specified on both item and variant",
)
}
fn trait_list() -> String {
[
"Clone",
"Copy",
"Debug",
"Default",
"Eq",
"Hash",
"Ord",
"PartialEq",
"PartialOrd",
#[cfg(feature = "zeroize")]
"Zeroize",
#[cfg(feature = "zeroize")]
"ZeroizeOnDrop",
]
.join(", ")
}
fn skip_group_list() -> String {
[
"Debug",
"EqHashOrd",
"Hash",
#[cfg(feature = "zeroize")]
"Zeroize",
]
.join(", ")
}
#[cfg(feature = "zeroize")]
pub fn zeroize(span: Span) -> syn::Error {
syn::Error::new(
span,
"`Zeroize` option is only supported if `Zeroize` is being implemented",
)
}
#[cfg(feature = "zeroize")]
pub fn deprecated_zeroize_drop(span: Span) -> syn::Error {
syn::Error::new(
span,
"`Zeroize(drop)` is deprecated, use `ZeroizeOnDrop` instead",
)
}
}