summaryrefslogtreecommitdiff
path: root/vendor/educe/src/common/where_predicates_bool.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/educe/src/common/where_predicates_bool.rs')
-rw-r--r--vendor/educe/src/common/where_predicates_bool.rs122
1 files changed, 122 insertions, 0 deletions
diff --git a/vendor/educe/src/common/where_predicates_bool.rs b/vendor/educe/src/common/where_predicates_bool.rs
new file mode 100644
index 00000000..4aa3695c
--- /dev/null
+++ b/vendor/educe/src/common/where_predicates_bool.rs
@@ -0,0 +1,122 @@
+use quote::{quote, ToTokens};
+use syn::{
+ parse::{Parse, ParseStream},
+ punctuated::Punctuated,
+ spanned::Spanned,
+ token::Comma,
+ Expr, GenericParam, Lit, Meta, MetaNameValue, Path, Token, Type, WherePredicate,
+};
+
+use super::path::path_to_string;
+
+pub(crate) type WherePredicates = Punctuated<WherePredicate, Token![,]>;
+
+pub(crate) enum WherePredicatesOrBool {
+ WherePredicates(WherePredicates),
+ Bool(bool),
+ All,
+}
+
+impl WherePredicatesOrBool {
+ fn from_lit(lit: &Lit) -> syn::Result<Self> {
+ Ok(match lit {
+ Lit::Bool(lit) => Self::Bool(lit.value),
+ Lit::Str(lit) => match lit.parse_with(WherePredicates::parse_terminated) {
+ Ok(where_predicates) => Self::WherePredicates(where_predicates),
+ Err(_) if lit.value().is_empty() => Self::Bool(false),
+ Err(error) => return Err(error),
+ },
+ other => {
+ return Err(syn::Error::new(
+ other.span(),
+ "unexpected kind of literal (only boolean or string allowed)",
+ ))
+ },
+ })
+ }
+}
+
+impl Parse for WherePredicatesOrBool {
+ #[inline]
+ fn parse(input: ParseStream) -> syn::Result<Self> {
+ if let Ok(lit) = input.parse::<Lit>() {
+ return Self::from_lit(&lit);
+ }
+
+ if let Ok(_star) = input.parse::<Token![*]>() {
+ return Ok(Self::All);
+ }
+
+ Ok(Self::WherePredicates(input.parse_terminated(WherePredicate::parse, Token![,])?))
+ }
+}
+
+#[inline]
+pub(crate) fn meta_name_value_2_where_predicates_bool(
+ name_value: &MetaNameValue,
+) -> syn::Result<WherePredicatesOrBool> {
+ if let Expr::Lit(lit) = &name_value.value {
+ return WherePredicatesOrBool::from_lit(&lit.lit);
+ }
+
+ Err(syn::Error::new(
+ name_value.value.span(),
+ format!(
+ "expected `{path} = \"where_predicates\"` or `{path} = false`",
+ path = path_to_string(&name_value.path)
+ ),
+ ))
+}
+
+#[inline]
+pub(crate) fn meta_2_where_predicates(meta: &Meta) -> syn::Result<WherePredicatesOrBool> {
+ match &meta {
+ Meta::NameValue(name_value) => meta_name_value_2_where_predicates_bool(name_value),
+ Meta::List(list) => list.parse_args::<WherePredicatesOrBool>(),
+ Meta::Path(path) => Err(syn::Error::new(
+ path.span(),
+ format!(
+ "expected `{path} = \"where_predicates\"`, `{path}(where_predicates)`, `{path} = \
+ false`, or `{path}(false)`",
+ path = path.clone().into_token_stream()
+ ),
+ )),
+ }
+}
+
+#[inline]
+pub(crate) fn create_where_predicates_from_all_generic_parameters(
+ params: &Punctuated<GenericParam, Comma>,
+ bound_trait: &Path,
+) -> WherePredicates {
+ let mut where_predicates = Punctuated::new();
+
+ for param in params {
+ if let GenericParam::Type(ty) = param {
+ let ident = &ty.ident;
+
+ where_predicates.push(syn::parse2(quote! { #ident: #bound_trait }).unwrap());
+ }
+ }
+
+ where_predicates
+}
+
+#[inline]
+pub(crate) fn create_where_predicates_from_generic_parameters_check_types(
+ bound_trait: &Path,
+ types: &[&Type],
+ supertraits: &[proc_macro2::TokenStream],
+) -> WherePredicates {
+ let mut where_predicates = Punctuated::new();
+
+ for t in types {
+ where_predicates.push(syn::parse2(quote! { #t: #bound_trait }).unwrap());
+ }
+
+ for supertrait in supertraits {
+ where_predicates.push(syn::parse2(quote! { Self: #supertrait }).unwrap());
+ }
+
+ where_predicates
+}