From 40cb326ed3686ddbc0784017552da4f8e818151c Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Thu, 4 Jul 2024 17:01:02 -0400 Subject: [PATCH 1/9] Remove unused ApiBaseUrl::by_extending --- wp_api/src/request/endpoint.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/wp_api/src/request/endpoint.rs b/wp_api/src/request/endpoint.rs index 36fb42e90..108f28eec 100644 --- a/wp_api/src/request/endpoint.rs +++ b/wp_api/src/request/endpoint.rs @@ -83,17 +83,6 @@ impl ApiBaseUrl { .expect("ApiBaseUrl is already parsed, so this can't result in an error") } - fn by_extending(&self, segments: I) -> Url - where - I: IntoIterator, - I::Item: AsRef, - { - self.url - .clone() - .extend(segments) - .expect("ApiBaseUrl is already parsed, so this can't result in an error") - } - pub fn by_extending_and_splitting_by_forward_slash(&self, segments: I) -> Url where I: IntoIterator, @@ -197,9 +186,17 @@ mod tests { format!("{}/bar", expected_wp_json_url) ); assert_eq!( - api_base_url.by_extending(["bar", "baz"]).as_str(), + api_base_url + .by_extending_and_splitting_by_forward_slash(["bar", "baz"]) + .as_str(), format!("{}/bar/baz", expected_wp_json_url) ); + assert_eq!( + api_base_url + .by_extending_and_splitting_by_forward_slash(["bar", "baz/quox"]) + .as_str(), + format!("{}/bar/baz/quox", expected_wp_json_url) + ); } fn wp_json_endpoint(base_url: &str) -> String { From 2ea203fb67c5f898c89cab21a2f8a69be044f581 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Thu, 4 Jul 2024 19:54:53 -0400 Subject: [PATCH 2/9] Add Namespace outer attr to WpDerivedRequest --- wp_api/src/request/endpoint.rs | 10 +- .../application_passwords_endpoint.rs | 1 + .../src/request/endpoint/plugins_endpoint.rs | 1 + wp_api/src/request/endpoint/users_endpoint.rs | 1 + wp_derive_request_builder/src/generate.rs | 9 +- .../generate/helpers_to_generate_tokens.rs | 33 +++-- wp_derive_request_builder/src/lib.rs | 2 +- wp_derive_request_builder/src/parse.rs | 11 +- .../src/sparse_field_attr.rs | 136 ++++++++++++++---- .../tests/pass/basic_derived_request.rs | 1 + 10 files changed, 155 insertions(+), 50 deletions(-) diff --git a/wp_api/src/request/endpoint.rs b/wp_api/src/request/endpoint.rs index 108f28eec..e2b9666e0 100644 --- a/wp_api/src/request/endpoint.rs +++ b/wp_api/src/request/endpoint.rs @@ -6,7 +6,7 @@ pub(crate) mod application_passwords_endpoint; pub(crate) mod plugins_endpoint; pub(crate) mod users_endpoint; -const WP_JSON_PATH_SEGMENTS: [&str; 3] = ["wp-json", "wp", "v2"]; +const WP_JSON_PATH_SEGMENTS: [&str; 1] = ["wp-json"]; uniffi::custom_newtype!(WpEndpointUrl, String); #[derive(Debug, Clone)] @@ -93,7 +93,10 @@ impl ApiBaseUrl { .extend(segments.into_iter().flat_map(|s| { s.as_ref() .split('/') - .map(str::to_string) + .filter_map(|x| match x.trim() { + "" => None, + y => Some(y.to_string()), + }) .collect::>() })) .expect("ApiBaseUrl is already parsed, so this can't result in an error") @@ -213,9 +216,10 @@ mod tests { } pub fn validate_endpoint(endpoint_url: ApiEndpointUrl, path: &str) { + let namespace = "/wp/v2"; assert_eq!( endpoint_url.as_str(), - format!("{}{}", fixture_api_base_url().as_str(), path) + format!("{}{}{}", fixture_api_base_url().as_str(), namespace, path) ); } } diff --git a/wp_api/src/request/endpoint/application_passwords_endpoint.rs b/wp_api/src/request/endpoint/application_passwords_endpoint.rs index b3d459d44..0eb04efa3 100644 --- a/wp_api/src/request/endpoint/application_passwords_endpoint.rs +++ b/wp_api/src/request/endpoint/application_passwords_endpoint.rs @@ -9,6 +9,7 @@ use crate::application_passwords::{ use crate::users::UserId; #[derive(WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(SparseApplicationPasswordField)] enum ApplicationPasswordsRequest { #[post(url = "/users//application-passwords", params = &ApplicationPasswordCreateParams, output = ApplicationPasswordWithEditContext)] diff --git a/wp_api/src/request/endpoint/plugins_endpoint.rs b/wp_api/src/request/endpoint/plugins_endpoint.rs index a1f819823..44620358c 100644 --- a/wp_api/src/request/endpoint/plugins_endpoint.rs +++ b/wp_api/src/request/endpoint/plugins_endpoint.rs @@ -6,6 +6,7 @@ use crate::{ use wp_derive_request_builder::WpDerivedRequest; #[derive(WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(SparsePluginField)] enum PluginsRequest { #[post(url = "/plugins", params = &PluginCreateParams, output = PluginWithEditContext)] diff --git a/wp_api/src/request/endpoint/users_endpoint.rs b/wp_api/src/request/endpoint/users_endpoint.rs index 2819c4bec..3c4dd25bb 100644 --- a/wp_api/src/request/endpoint/users_endpoint.rs +++ b/wp_api/src/request/endpoint/users_endpoint.rs @@ -6,6 +6,7 @@ use crate::{ use wp_derive_request_builder::WpDerivedRequest; #[derive(WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(SparseUserField)] enum UsersRequest { #[contextual_get(url = "/users", params = &UserListParams, output = Vec)] diff --git a/wp_derive_request_builder/src/generate.rs b/wp_derive_request_builder/src/generate.rs index 5988e17c1..8c9193cfd 100644 --- a/wp_derive_request_builder/src/generate.rs +++ b/wp_derive_request_builder/src/generate.rs @@ -10,7 +10,7 @@ use syn::Ident; use crate::{ parse::{ParsedEnum, ParsedVariant, RequestType}, - sparse_field_attr::SparseFieldAttr, + sparse_field_attr::{NamespaceAttr, SparseFieldAttr}, }; mod helpers_to_generate_tokens; @@ -165,7 +165,8 @@ fn generate_endpoint_type(config: &Config, parsed_enum: &ParsedEnum) -> TokenStr let url_parts = variant.attr.url_parts.as_slice(); let params_type = &variant.attr.params; let request_type = variant.attr.request_type; - let url_from_api_base_url = fn_body_get_url_from_api_base_url(url_parts); + let url_from_api_base_url = + fn_body_get_url_from_api_base_url(&config.namespace_attr, url_parts); let query_pairs = fn_body_query_pairs(params_type, request_type); ContextAndFilterHandler::from_request_type(request_type) @@ -268,6 +269,7 @@ impl Display for WpContext { pub struct Config { pub crate_ident: Ident, pub sparse_field_type: SparseFieldAttr, + pub namespace_attr: NamespaceAttr, pub generated_idents: ConfigGeneratedIdents, pub static_types: ConfigStaticTypes, } @@ -287,7 +289,8 @@ impl Config { Self { crate_ident, - sparse_field_type: parsed_enum.sparse_field_attr.clone(), + sparse_field_type: parsed_enum.outer_attr.sparse_field_attr.clone(), + namespace_attr: parsed_enum.outer_attr.namespace_attr.clone(), generated_idents, static_types, } diff --git a/wp_derive_request_builder/src/generate/helpers_to_generate_tokens.rs b/wp_derive_request_builder/src/generate/helpers_to_generate_tokens.rs index 585adef96..5d77c7507 100644 --- a/wp_derive_request_builder/src/generate/helpers_to_generate_tokens.rs +++ b/wp_derive_request_builder/src/generate/helpers_to_generate_tokens.rs @@ -6,7 +6,7 @@ use syn::Ident; use super::{ContextAndFilterHandler, PartOf, WpContext}; use crate::{ parse::{ParsedEnum, RequestType}, - sparse_field_attr::SparseFieldAttr, + sparse_field_attr::{NamespaceAttr, SparseFieldAttr}, variant_attr::{ParamsType, UrlPart}, }; @@ -224,7 +224,10 @@ fn fn_arg_fields(context_and_filter_handler: ContextAndFilterHandler) -> TokenSt } } -pub fn fn_body_get_url_from_api_base_url(url_parts: &[UrlPart]) -> TokenStream { +pub fn fn_body_get_url_from_api_base_url( + namespace_attr: &NamespaceAttr, + url_parts: &[UrlPart], +) -> TokenStream { let url_parts = url_parts .iter() .map(|part| match part { @@ -235,8 +238,9 @@ pub fn fn_body_get_url_from_api_base_url(url_parts: &[UrlPart]) -> TokenStream { UrlPart::Static(static_part) => quote! { #static_part }, }) .collect::>(); + let namespace = namespace_attr.token.clone(); quote! { - let mut url = self.api_base_url.by_extending_and_splitting_by_forward_slash([ #(#url_parts,)* ]); + let mut url = self.api_base_url.by_extending_and_splitting_by_forward_slash([ #namespace, #(#url_parts,)* ]); } } @@ -378,9 +382,12 @@ pub fn fn_body_get_request_from_request_builder( #[cfg(test)] mod tests { #![allow(clippy::too_many_arguments)] + use std::str::FromStr; + use crate::sparse_field_attr; use super::*; + use proc_macro2::Literal; use quote::ToTokens; use rstest::rstest; use syn::parse_quote; @@ -910,34 +917,40 @@ mod tests { #[rstest] #[case( url_static_users(), - "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"users\" ,]) ;" + "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"/wp/v2\" , \"users\" ,]) ;" )] #[case( url_users_with_user_id(), - "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"users\" , & user_id . to_string () ,]) ;" + "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"/wp/v2\" , \"users\" , & user_id . to_string () ,]) ;" )] #[case( url_users_with_user_id(), - "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"users\" , & user_id . to_string () ,]) ;" + "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"/wp/v2\" , \"users\" , & user_id . to_string () ,]) ;" )] #[case( vec![UrlPart::Dynamic("user_id".to_string()), UrlPart::Dynamic("user_type".to_string())], - "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([& user_id . to_string () , & user_type . to_string () ,]) ;" + "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"/wp/v2\" , & user_id . to_string () , & user_type . to_string () ,]) ;" )] #[case( vec![UrlPart::Static("users".to_string()), UrlPart::Dynamic("user_id".to_string()), UrlPart::Dynamic("user_type".to_string()), ], - "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"users\" , & user_id . to_string () , & user_type . to_string () ,]) ;" + "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"/wp/v2\" , \"users\" , & user_id . to_string () , & user_type . to_string () ,]) ;" )] #[case( vec![UrlPart::Static("users".to_string()), UrlPart::Static("me".to_string()), UrlPart::Dynamic("user_id".to_string()), UrlPart::Dynamic("user_type".to_string()), ], - "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"users\" , \"me\" , & user_id . to_string () , & user_type . to_string () ,]) ;" + "let mut url = self . api_base_url . by_extending_and_splitting_by_forward_slash ([\"/wp/v2\" , \"users\" , \"me\" , & user_id . to_string () , & user_type . to_string () ,]) ;" )] fn test_fn_body_get_url_from_api_base_url( #[case] url_parts: Vec, #[case] expected_str: &str, ) { assert_eq!( - fn_body_get_url_from_api_base_url(&url_parts).to_string(), + fn_body_get_url_from_api_base_url( + &NamespaceAttr { + token: quote! { "/wp/v2" }.into_iter().next().unwrap(), + }, + &url_parts + ) + .to_string(), expected_str ); } diff --git a/wp_derive_request_builder/src/lib.rs b/wp_derive_request_builder/src/lib.rs index 728f1a103..80cccccec 100644 --- a/wp_derive_request_builder/src/lib.rs +++ b/wp_derive_request_builder/src/lib.rs @@ -9,7 +9,7 @@ mod variant_attr; #[proc_macro_derive( WpDerivedRequest, - attributes(SparseField, post, delete, contextual_get) + attributes(SparseField, Namespace, post, delete, contextual_get) )] pub fn derive(input: TokenStream) -> TokenStream { let parsed_enum = parse_macro_input!(input as parse::ParsedEnum); diff --git a/wp_derive_request_builder/src/parse.rs b/wp_derive_request_builder/src/parse.rs index dbf4c03e7..8b252e17f 100644 --- a/wp_derive_request_builder/src/parse.rs +++ b/wp_derive_request_builder/src/parse.rs @@ -11,24 +11,27 @@ use syn::{ Ident, Token, }; -use crate::{sparse_field_attr::SparseFieldAttr, variant_attr::ParsedVariantAttribute}; +use crate::{ + sparse_field_attr::{OuterAttr, SparseFieldAttr}, + variant_attr::ParsedVariantAttribute, +}; #[derive(Debug, Clone)] pub struct ParsedEnum { - pub sparse_field_attr: SparseFieldAttr, + pub outer_attr: OuterAttr, pub enum_ident: Ident, pub variants: Punctuated, } impl Parse for ParsedEnum { fn parse(input: ParseStream) -> syn::Result { - let sparse_field_attr = input.parse()?; + let outer_attr = input.parse()?; let _enum_token: Token![enum] = input.parse()?; let enum_ident: Ident = input.parse()?; let content: ParseBuffer; let brace_token = braced!(content in input); Ok(Self { - sparse_field_attr, + outer_attr, enum_ident, variants: content.parse_terminated(ParsedVariant::parse, Token![,])?, }) diff --git a/wp_derive_request_builder/src/sparse_field_attr.rs b/wp_derive_request_builder/src/sparse_field_attr.rs index f7247952e..dd784bead 100644 --- a/wp_derive_request_builder/src/sparse_field_attr.rs +++ b/wp_derive_request_builder/src/sparse_field_attr.rs @@ -1,53 +1,131 @@ -use proc_macro2::{TokenStream, TokenTree}; +use proc_macro2::{Literal, TokenStream, TokenTree}; use syn::{ parse::{Parse, ParseStream}, spanned::Spanned, Attribute, Ident, Meta, MetaList, Result, }; +#[derive(Debug, Clone)] +pub struct NamespaceAttr { + pub token: TokenTree, +} + +impl TryFrom for NamespaceAttr { + type Error = OuterAttrParseError; + + fn try_from(value: TokenStream) -> std::result::Result { + let mut iter = value.into_iter(); + if let Some(first) = iter.next() { + if iter.next().is_some() { + // Has more than one token + Err(OuterAttrParseError::WrongNamespaceAttrFormat) + } else { + if let TokenTree::Literal(_) = first { + Ok(Self { token: first }) + } else { + // Is not a literal + Err(OuterAttrParseError::NamespaceAttrIsNotLiteral) + } + } + } else { + // Doesn't have any tokens + Err(OuterAttrParseError::WrongNamespaceAttrFormat) + } + } +} + #[derive(Debug, Clone)] pub struct SparseFieldAttr { pub tokens: TokenStream, } -impl Parse for SparseFieldAttr { +#[derive(Debug, Clone)] +pub struct OuterAttr { + pub namespace_attr: NamespaceAttr, + pub sparse_field_attr: SparseFieldAttr, +} + +impl Parse for OuterAttr { fn parse(input: ParseStream) -> Result { - let attr = { - let attrs = Attribute::parse_outer(input)?; - if attrs.is_empty() { - return Err( - SparseFieldParseError::MissingSparseFieldAttr.into_syn_error(input.span()) - ); - } else if attrs.len() > 1 { - return Err( - SparseFieldParseError::MoreThanOneOuterAttr.into_syn_error(input.span()) - ); - } - attrs - .first() - .expect("Already verified that there is a single attr") - .to_owned() - }; - - if let Meta::List(MetaList { tokens, .. }) = attr.meta { - Ok(Self { tokens }) - } else { - Err(SparseFieldParseError::WrongFormat.into_syn_error(attr.span())) + let attrs = Attribute::parse_outer(input)?; + if attrs.is_empty() { + return Err(OuterAttrParseError::NoOuterAttrs.into_syn_error(input.span())); + } else if attrs.len() > 2 { + return Err(OuterAttrParseError::UnexpectedNumberOfAttrs.into_syn_error(input.span())); } + + let pairs = attrs + .into_iter() + .map(|a| { + let error_span = a.span().clone(); + if let Meta::List(meta_list) = a.meta { + if meta_list.path.segments.len() != 1 { + Err(OuterAttrParseError::UnexpectedAttrPathSegmentCount + .into_syn_error(error_span)) + } else { + let s = meta_list + .path + .segments + .first() + .expect("Already verified that there is only one segment"); + Ok((s.ident.to_string(), meta_list.tokens)) + } + } else { + Err(OuterAttrParseError::WrongOuterAttrFormat.into_syn_error(error_span)) + } + }) + .collect::>>()?; + let (sparse_field, namespace) = + pairs + .into_iter() + .fold(Ok((None, None)), |acc, (k, tokens)| match k.as_str() { + "SparseField" => acc.map(|acc| (Some(tokens), acc.1)), + "Namespace" => acc.map(|acc| (acc.0, Some(tokens))), + _ => Err(OuterAttrParseError::UnexpectedAttr.into_syn_error(input.span())), + })?; + let sparse_field_attr = sparse_field + .map(|tokens| SparseFieldAttr { tokens }) + .ok_or(OuterAttrParseError::MissingSparseFieldAttr.into_syn_error(input.span()))?; + let namespace_attr = namespace + .ok_or(OuterAttrParseError::MissingNamespaceAttr.into_syn_error(input.span())) + .and_then(|t| NamespaceAttr::try_from(t).map_err(|e| e.into_syn_error(input.span())))?; + + Ok(Self { + namespace_attr, + sparse_field_attr, + }) } } #[derive(Debug, thiserror::Error)] -enum SparseFieldParseError { +pub enum OuterAttrParseError { + #[error("Expecting #[Namespace(\"_path_\")] - Did you forget (\"\")?")] + NamespaceAttrIsNotLiteral, + #[error("Expecting #[Namespace(\"_path_\")] - Found extra tokens")] + NamespaceAttrHasMultipleTokens, + #[error("Missing #[SparseField(_field_type_) & #[Namespace(\"_path_\")] attributes]")] + NoOuterAttrs, + #[error("Missing #[Namespace(\"_path_\")]")] + MissingNamespaceAttr, #[error("Missing #[SparseField(_field_type_)]")] MissingSparseFieldAttr, - #[error("Only a single #[SparseField(_field_type_)] attribute is supported")] - MoreThanOneOuterAttr, - #[error("Expecting #[SparseField(_field_type_)]")] - WrongFormat, + #[error( + "Only #[SparseField(_field_type_)] & #[Namespace(\"_path_\")] attributes are supported" + )] + UnexpectedNumberOfAttrs, + #[error("Only SparseField & Namespace attributes only have one path segment")] + UnexpectedAttrPathSegmentCount, + #[error("Expecting #[SparseField(_field_type_)] & #[Namespace(\"_path_\")]")] + WrongOuterAttrFormat, + #[error("Expecting #[Namespace(\"_path_\")]")] + WrongNamespaceAttrFormat, + #[error( + "Only #[SparseField(_field_type_)] & #[Namespace(\"_path_\")] attributes are supported" + )] + UnexpectedAttr, } -impl SparseFieldParseError { +impl OuterAttrParseError { fn into_syn_error(self, span: proc_macro2::Span) -> syn::Error { syn::Error::new(span, self.to_string()) } diff --git a/wp_derive_request_builder/tests/pass/basic_derived_request.rs b/wp_derive_request_builder/tests/pass/basic_derived_request.rs index b6ab241b1..5c7d2bbd7 100644 --- a/wp_derive_request_builder/tests/pass/basic_derived_request.rs +++ b/wp_derive_request_builder/tests/pass/basic_derived_request.rs @@ -1,5 +1,6 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] #[SparseField(crate::SparseUserField)] +#[Namespace("/wp/v2")] enum UsersRequest { #[contextual_get(url = "/users", params = &UserListParams, output = Vec)] List, From 6ef87106986f00ae18977e9c3eb8ea73dfa87841 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Fri, 5 Jul 2024 13:45:55 -0400 Subject: [PATCH 3/9] Rename sparse_field_attr module to outer_attr --- wp_derive_request_builder/src/generate.rs | 2 +- .../src/generate/helpers_to_generate_tokens.rs | 4 +--- wp_derive_request_builder/src/lib.rs | 2 +- .../src/{sparse_field_attr.rs => outer_attr.rs} | 0 wp_derive_request_builder/src/parse.rs | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) rename wp_derive_request_builder/src/{sparse_field_attr.rs => outer_attr.rs} (100%) diff --git a/wp_derive_request_builder/src/generate.rs b/wp_derive_request_builder/src/generate.rs index 8c9193cfd..64b0bdeee 100644 --- a/wp_derive_request_builder/src/generate.rs +++ b/wp_derive_request_builder/src/generate.rs @@ -9,8 +9,8 @@ use strum_macros::EnumIter; use syn::Ident; use crate::{ + outer_attr::{NamespaceAttr, SparseFieldAttr}, parse::{ParsedEnum, ParsedVariant, RequestType}, - sparse_field_attr::{NamespaceAttr, SparseFieldAttr}, }; mod helpers_to_generate_tokens; diff --git a/wp_derive_request_builder/src/generate/helpers_to_generate_tokens.rs b/wp_derive_request_builder/src/generate/helpers_to_generate_tokens.rs index 5d77c7507..1deef35ce 100644 --- a/wp_derive_request_builder/src/generate/helpers_to_generate_tokens.rs +++ b/wp_derive_request_builder/src/generate/helpers_to_generate_tokens.rs @@ -5,8 +5,8 @@ use syn::Ident; use super::{ContextAndFilterHandler, PartOf, WpContext}; use crate::{ + outer_attr::{NamespaceAttr, SparseFieldAttr}, parse::{ParsedEnum, RequestType}, - sparse_field_attr::{NamespaceAttr, SparseFieldAttr}, variant_attr::{ParamsType, UrlPart}, }; @@ -384,8 +384,6 @@ mod tests { #![allow(clippy::too_many_arguments)] use std::str::FromStr; - use crate::sparse_field_attr; - use super::*; use proc_macro2::Literal; use quote::ToTokens; diff --git a/wp_derive_request_builder/src/lib.rs b/wp_derive_request_builder/src/lib.rs index 80cccccec..d226c2264 100644 --- a/wp_derive_request_builder/src/lib.rs +++ b/wp_derive_request_builder/src/lib.rs @@ -3,8 +3,8 @@ use proc_macro::TokenStream; use syn::parse_macro_input; mod generate; +mod outer_attr; mod parse; -mod sparse_field_attr; mod variant_attr; #[proc_macro_derive( diff --git a/wp_derive_request_builder/src/sparse_field_attr.rs b/wp_derive_request_builder/src/outer_attr.rs similarity index 100% rename from wp_derive_request_builder/src/sparse_field_attr.rs rename to wp_derive_request_builder/src/outer_attr.rs diff --git a/wp_derive_request_builder/src/parse.rs b/wp_derive_request_builder/src/parse.rs index 8b252e17f..399ce8c42 100644 --- a/wp_derive_request_builder/src/parse.rs +++ b/wp_derive_request_builder/src/parse.rs @@ -12,7 +12,7 @@ use syn::{ }; use crate::{ - sparse_field_attr::{OuterAttr, SparseFieldAttr}, + outer_attr::{OuterAttr, SparseFieldAttr}, variant_attr::ParsedVariantAttribute, }; From dc4823afc5e5ed52148abe4c6987b726d1dc4792 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Fri, 5 Jul 2024 14:02:44 -0400 Subject: [PATCH 4/9] Add Namespace to wp_derive_request_builder tests --- wp_derive_request_builder/src/outer_attr.rs | 18 ++++++++---------- .../tests/fail/missing_sparse_field_attr.rs | 1 + .../tests/fail/missing_url.rs | 1 + .../tests/fail/multiple_sparse_field_attr.rs | 1 + .../tests/fail/not_equals_sign.rs | 1 + .../tests/fail/output_not_ident.rs | 1 + .../tests/fail/params_not_ident.rs | 1 + .../tests/fail/url_not_ident.rs | 1 + .../tests/fail/url_value_not_literal.rs | 1 + .../tests/pass/basic_derived_request.rs | 2 +- .../tests/pass/multi_segment_output.rs | 1 + .../tests/pass/multi_segment_params.rs | 1 + .../tests/pass/optional_params.rs | 1 + 13 files changed, 20 insertions(+), 11 deletions(-) diff --git a/wp_derive_request_builder/src/outer_attr.rs b/wp_derive_request_builder/src/outer_attr.rs index dd784bead..50098176d 100644 --- a/wp_derive_request_builder/src/outer_attr.rs +++ b/wp_derive_request_builder/src/outer_attr.rs @@ -19,13 +19,11 @@ impl TryFrom for NamespaceAttr { if iter.next().is_some() { // Has more than one token Err(OuterAttrParseError::WrongNamespaceAttrFormat) + } else if let TokenTree::Literal(_) = first { + Ok(Self { token: first }) } else { - if let TokenTree::Literal(_) = first { - Ok(Self { token: first }) - } else { - // Is not a literal - Err(OuterAttrParseError::NamespaceAttrIsNotLiteral) - } + // Is not a literal + Err(OuterAttrParseError::NamespaceAttrIsNotLiteral) } } else { // Doesn't have any tokens @@ -57,7 +55,7 @@ impl Parse for OuterAttr { let pairs = attrs .into_iter() .map(|a| { - let error_span = a.span().clone(); + let error_span = a.span(); if let Meta::List(meta_list) = a.meta { if meta_list.path.segments.len() != 1 { Err(OuterAttrParseError::UnexpectedAttrPathSegmentCount @@ -78,9 +76,9 @@ impl Parse for OuterAttr { let (sparse_field, namespace) = pairs .into_iter() - .fold(Ok((None, None)), |acc, (k, tokens)| match k.as_str() { - "SparseField" => acc.map(|acc| (Some(tokens), acc.1)), - "Namespace" => acc.map(|acc| (acc.0, Some(tokens))), + .try_fold((None, None), |acc, (k, tokens)| match k.as_str() { + "SparseField" => Ok((Some(tokens), acc.1)), + "Namespace" => Ok((acc.0, Some(tokens))), _ => Err(OuterAttrParseError::UnexpectedAttr.into_syn_error(input.span())), })?; let sparse_field_attr = sparse_field diff --git a/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.rs b/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.rs index e8a0fe883..333393a76 100644 --- a/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.rs +++ b/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] enum UsersRequest { #[contextual_get(url = "/users", output = std::vec::Vec)] List, diff --git a/wp_derive_request_builder/tests/fail/missing_url.rs b/wp_derive_request_builder/tests/fail/missing_url.rs index 063224066..c45579efa 100644 --- a/wp_derive_request_builder/tests/fail/missing_url.rs +++ b/wp_derive_request_builder/tests/fail/missing_url.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get(params = &UserListParams, output = Vec)] diff --git a/wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.rs b/wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.rs index c8edc713b..4d5613011 100644 --- a/wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.rs +++ b/wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] #[SparseField(crate::SparsePluginField)] enum UsersRequest { diff --git a/wp_derive_request_builder/tests/fail/not_equals_sign.rs b/wp_derive_request_builder/tests/fail/not_equals_sign.rs index efb6883c8..ab8968b58 100644 --- a/wp_derive_request_builder/tests/fail/not_equals_sign.rs +++ b/wp_derive_request_builder/tests/fail/not_equals_sign.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get(url : "/users", params = &UserListParams, output = Vec)] diff --git a/wp_derive_request_builder/tests/fail/output_not_ident.rs b/wp_derive_request_builder/tests/fail/output_not_ident.rs index 5eb0e83d3..f8e757cdb 100644 --- a/wp_derive_request_builder/tests/fail/output_not_ident.rs +++ b/wp_derive_request_builder/tests/fail/output_not_ident.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get(url = "/users", params = &UserListParams, "output" = Vec)] diff --git a/wp_derive_request_builder/tests/fail/params_not_ident.rs b/wp_derive_request_builder/tests/fail/params_not_ident.rs index d4ecb9ea5..45f0828b4 100644 --- a/wp_derive_request_builder/tests/fail/params_not_ident.rs +++ b/wp_derive_request_builder/tests/fail/params_not_ident.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get(url = "/users", "params" = &UserListParams, output = Vec)] diff --git a/wp_derive_request_builder/tests/fail/url_not_ident.rs b/wp_derive_request_builder/tests/fail/url_not_ident.rs index 66c2d0cb9..a49e11e58 100644 --- a/wp_derive_request_builder/tests/fail/url_not_ident.rs +++ b/wp_derive_request_builder/tests/fail/url_not_ident.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get("url" = "/users", params = &UserListParams, output = Vec)] diff --git a/wp_derive_request_builder/tests/fail/url_value_not_literal.rs b/wp_derive_request_builder/tests/fail/url_value_not_literal.rs index cb7826539..8c4ac23ea 100644 --- a/wp_derive_request_builder/tests/fail/url_value_not_literal.rs +++ b/wp_derive_request_builder/tests/fail/url_value_not_literal.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get(url = users, params = &UserListParams, output = Vec)] diff --git a/wp_derive_request_builder/tests/pass/basic_derived_request.rs b/wp_derive_request_builder/tests/pass/basic_derived_request.rs index 5c7d2bbd7..3798a70c3 100644 --- a/wp_derive_request_builder/tests/pass/basic_derived_request.rs +++ b/wp_derive_request_builder/tests/pass/basic_derived_request.rs @@ -1,6 +1,6 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] -#[SparseField(crate::SparseUserField)] #[Namespace("/wp/v2")] +#[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get(url = "/users", params = &UserListParams, output = Vec)] List, diff --git a/wp_derive_request_builder/tests/pass/multi_segment_output.rs b/wp_derive_request_builder/tests/pass/multi_segment_output.rs index e1bb054cc..31c5806fc 100644 --- a/wp_derive_request_builder/tests/pass/multi_segment_output.rs +++ b/wp_derive_request_builder/tests/pass/multi_segment_output.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get(url = "/users", output = std::vec::Vec)] diff --git a/wp_derive_request_builder/tests/pass/multi_segment_params.rs b/wp_derive_request_builder/tests/pass/multi_segment_params.rs index ebe67f477..3f076587a 100644 --- a/wp_derive_request_builder/tests/pass/multi_segment_params.rs +++ b/wp_derive_request_builder/tests/pass/multi_segment_params.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get(url = "/users", params = &crate::UserListParams, output = Vec)] diff --git a/wp_derive_request_builder/tests/pass/optional_params.rs b/wp_derive_request_builder/tests/pass/optional_params.rs index cfda1dca1..3331d0c2f 100644 --- a/wp_derive_request_builder/tests/pass/optional_params.rs +++ b/wp_derive_request_builder/tests/pass/optional_params.rs @@ -1,4 +1,5 @@ #[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] enum UsersRequest { #[contextual_get(url = "/users", output = Vec)] From 64c366099e30dee49a1fa261d32cda82f71e1084 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Fri, 5 Jul 2024 14:18:02 -0400 Subject: [PATCH 5/9] Update wp_derive_request_builder test failures for namespace changes --- .../tests/fail/missing_sparse_field_attr.stderr | 4 ++-- wp_derive_request_builder/tests/fail/missing_url.stderr | 4 ++-- wp_derive_request_builder/tests/fail/not_equals_sign.stderr | 4 ++-- wp_derive_request_builder/tests/fail/output_not_ident.stderr | 4 ++-- wp_derive_request_builder/tests/fail/params_not_ident.stderr | 4 ++-- wp_derive_request_builder/tests/fail/url_not_ident.stderr | 4 ++-- .../tests/fail/url_value_not_literal.stderr | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.stderr b/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.stderr index 9fd025588..4ab614797 100644 --- a/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.stderr +++ b/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.stderr @@ -1,5 +1,5 @@ error: Missing #[SparseField(_field_type_)] - --> tests/fail/missing_sparse_field_attr.rs:2:1 + --> tests/fail/missing_sparse_field_attr.rs:3:1 | -2 | enum UsersRequest { +3 | enum UsersRequest { | ^^^^ diff --git a/wp_derive_request_builder/tests/fail/missing_url.stderr b/wp_derive_request_builder/tests/fail/missing_url.stderr index f6e0721d0..fdd40faae 100644 --- a/wp_derive_request_builder/tests/fail/missing_url.stderr +++ b/wp_derive_request_builder/tests/fail/missing_url.stderr @@ -1,5 +1,5 @@ error: Missing (url = "/foo") - --> tests/fail/missing_url.rs:4:7 + --> tests/fail/missing_url.rs:5:7 | -4 | #[contextual_get(params = &UserListParams, output = Vec)] +5 | #[contextual_get(params = &UserListParams, output = Vec)] | ^^^^^^^^^^^^^^ diff --git a/wp_derive_request_builder/tests/fail/not_equals_sign.stderr b/wp_derive_request_builder/tests/fail/not_equals_sign.stderr index 7b2fdc2c7..5b4550161 100644 --- a/wp_derive_request_builder/tests/fail/not_equals_sign.stderr +++ b/wp_derive_request_builder/tests/fail/not_equals_sign.stderr @@ -1,5 +1,5 @@ error: Did you mean '='? - --> tests/fail/not_equals_sign.rs:4:26 + --> tests/fail/not_equals_sign.rs:5:26 | -4 | #[contextual_get(url : "/users", params = &UserListParams, output = Vec)] +5 | #[contextual_get(url : "/users", params = &UserListParams, output = Vec)] | ^ diff --git a/wp_derive_request_builder/tests/fail/output_not_ident.stderr b/wp_derive_request_builder/tests/fail/output_not_ident.stderr index feaede8ae..27416b39d 100644 --- a/wp_derive_request_builder/tests/fail/output_not_ident.stderr +++ b/wp_derive_request_builder/tests/fail/output_not_ident.stderr @@ -1,5 +1,5 @@ error: Expecting key value pairs (url = "", params = FooParam, output = FooOutput) - --> tests/fail/output_not_ident.rs:4:64 + --> tests/fail/output_not_ident.rs:5:64 | -4 | #[contextual_get(url = "/users", params = &UserListParams, "output" = Vec)] +5 | #[contextual_get(url = "/users", params = &UserListParams, "output" = Vec)] | ^^^^^^^^ diff --git a/wp_derive_request_builder/tests/fail/params_not_ident.stderr b/wp_derive_request_builder/tests/fail/params_not_ident.stderr index 73badd232..a30b0f723 100644 --- a/wp_derive_request_builder/tests/fail/params_not_ident.stderr +++ b/wp_derive_request_builder/tests/fail/params_not_ident.stderr @@ -1,5 +1,5 @@ error: Expecting key value pairs (url = "", params = FooParam, output = FooOutput) - --> tests/fail/params_not_ident.rs:4:38 + --> tests/fail/params_not_ident.rs:5:38 | -4 | #[contextual_get(url = "/users", "params" = &UserListParams, output = Vec)] +5 | #[contextual_get(url = "/users", "params" = &UserListParams, output = Vec)] | ^^^^^^^^ diff --git a/wp_derive_request_builder/tests/fail/url_not_ident.stderr b/wp_derive_request_builder/tests/fail/url_not_ident.stderr index 87cd2b99a..b7ffd5694 100644 --- a/wp_derive_request_builder/tests/fail/url_not_ident.stderr +++ b/wp_derive_request_builder/tests/fail/url_not_ident.stderr @@ -1,5 +1,5 @@ error: Expecting key value pairs (url = "", params = FooParam, output = FooOutput) - --> tests/fail/url_not_ident.rs:4:22 + --> tests/fail/url_not_ident.rs:5:22 | -4 | #[contextual_get("url" = "/users", params = &UserListParams, output = Vec)] +5 | #[contextual_get("url" = "/users", params = &UserListParams, output = Vec)] | ^^^^^ diff --git a/wp_derive_request_builder/tests/fail/url_value_not_literal.stderr b/wp_derive_request_builder/tests/fail/url_value_not_literal.stderr index e8ba0b19e..3caced9b1 100644 --- a/wp_derive_request_builder/tests/fail/url_value_not_literal.stderr +++ b/wp_derive_request_builder/tests/fail/url_value_not_literal.stderr @@ -1,5 +1,5 @@ error: Url should be set as a String: (url = "/foo") - --> tests/fail/url_value_not_literal.rs:4:28 + --> tests/fail/url_value_not_literal.rs:5:28 | -4 | #[contextual_get(url = users, params = &UserListParams, output = Vec)] +5 | #[contextual_get(url = users, params = &UserListParams, output = Vec)] | ^^^^^ From 5a552d7c8c2df2e94c2a291b63e50ea6b6a8dfb4 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Fri, 5 Jul 2024 14:31:37 -0400 Subject: [PATCH 6/9] Add support for external attrs in wp_derive_request_builder --- wp_derive_request_builder/src/outer_attr.rs | 65 +++++++------------ .../tests/fail/missing_namespace_attr.rs | 8 +++ .../tests/fail/missing_namespace_attr.stderr | 5 ++ .../fail/multiple_sparse_field_attr.stderr | 5 -- .../external_outer_attr.rs} | 4 +- 5 files changed, 38 insertions(+), 49 deletions(-) create mode 100644 wp_derive_request_builder/tests/fail/missing_namespace_attr.rs create mode 100644 wp_derive_request_builder/tests/fail/missing_namespace_attr.stderr delete mode 100644 wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.stderr rename wp_derive_request_builder/tests/{fail/multiple_sparse_field_attr.rs => pass/external_outer_attr.rs} (65%) diff --git a/wp_derive_request_builder/src/outer_attr.rs b/wp_derive_request_builder/src/outer_attr.rs index 50098176d..a87a2f4cd 100644 --- a/wp_derive_request_builder/src/outer_attr.rs +++ b/wp_derive_request_builder/src/outer_attr.rs @@ -46,41 +46,32 @@ pub struct OuterAttr { impl Parse for OuterAttr { fn parse(input: ParseStream) -> Result { let attrs = Attribute::parse_outer(input)?; - if attrs.is_empty() { - return Err(OuterAttrParseError::NoOuterAttrs.into_syn_error(input.span())); - } else if attrs.len() > 2 { - return Err(OuterAttrParseError::UnexpectedNumberOfAttrs.into_syn_error(input.span())); - } - let pairs = attrs - .into_iter() - .map(|a| { - let error_span = a.span(); - if let Meta::List(meta_list) = a.meta { - if meta_list.path.segments.len() != 1 { - Err(OuterAttrParseError::UnexpectedAttrPathSegmentCount - .into_syn_error(error_span)) - } else { - let s = meta_list - .path - .segments - .first() - .expect("Already verified that there is only one segment"); - Ok((s.ident.to_string(), meta_list.tokens)) - } + let (sparse_field, namespace) = attrs.into_iter().try_fold((None, None), |acc, a| { + let error_span = a.span(); + if let Meta::List(meta_list) = a.meta { + if meta_list.path.segments.len() != 1 { + Err(OuterAttrParseError::UnexpectedAttrPathSegmentCount + .into_syn_error(error_span)) } else { - Err(OuterAttrParseError::WrongOuterAttrFormat.into_syn_error(error_span)) + let s = meta_list + .path + .segments + .first() + .expect("Already verified that there is only one segment"); + + match s.ident.to_string().as_str() { + "SparseField" => Ok((Some(meta_list.tokens), acc.1)), + "Namespace" => Ok((acc.0, Some(meta_list.tokens))), + // Unrecognized attribute may belong to another Derive macro, so we need + // to ignore and not return an error + _ => Ok(acc), + } } - }) - .collect::>>()?; - let (sparse_field, namespace) = - pairs - .into_iter() - .try_fold((None, None), |acc, (k, tokens)| match k.as_str() { - "SparseField" => Ok((Some(tokens), acc.1)), - "Namespace" => Ok((acc.0, Some(tokens))), - _ => Err(OuterAttrParseError::UnexpectedAttr.into_syn_error(input.span())), - })?; + } else { + Err(OuterAttrParseError::WrongOuterAttrFormat.into_syn_error(error_span)) + } + })?; let sparse_field_attr = sparse_field .map(|tokens| SparseFieldAttr { tokens }) .ok_or(OuterAttrParseError::MissingSparseFieldAttr.into_syn_error(input.span()))?; @@ -101,26 +92,16 @@ pub enum OuterAttrParseError { NamespaceAttrIsNotLiteral, #[error("Expecting #[Namespace(\"_path_\")] - Found extra tokens")] NamespaceAttrHasMultipleTokens, - #[error("Missing #[SparseField(_field_type_) & #[Namespace(\"_path_\")] attributes]")] - NoOuterAttrs, #[error("Missing #[Namespace(\"_path_\")]")] MissingNamespaceAttr, #[error("Missing #[SparseField(_field_type_)]")] MissingSparseFieldAttr, - #[error( - "Only #[SparseField(_field_type_)] & #[Namespace(\"_path_\")] attributes are supported" - )] - UnexpectedNumberOfAttrs, #[error("Only SparseField & Namespace attributes only have one path segment")] UnexpectedAttrPathSegmentCount, #[error("Expecting #[SparseField(_field_type_)] & #[Namespace(\"_path_\")]")] WrongOuterAttrFormat, #[error("Expecting #[Namespace(\"_path_\")]")] WrongNamespaceAttrFormat, - #[error( - "Only #[SparseField(_field_type_)] & #[Namespace(\"_path_\")] attributes are supported" - )] - UnexpectedAttr, } impl OuterAttrParseError { diff --git a/wp_derive_request_builder/tests/fail/missing_namespace_attr.rs b/wp_derive_request_builder/tests/fail/missing_namespace_attr.rs new file mode 100644 index 000000000..d3bfc1708 --- /dev/null +++ b/wp_derive_request_builder/tests/fail/missing_namespace_attr.rs @@ -0,0 +1,8 @@ +#[derive(wp_derive_request_builder::WpDerivedRequest, serde::Serialize)] +#[SparseField(crate::SparseUserField)] +enum UsersRequest { + #[contextual_get(url = "/users", params = &UserListParams, output = Vec)] + List, +} + +fn main() {} diff --git a/wp_derive_request_builder/tests/fail/missing_namespace_attr.stderr b/wp_derive_request_builder/tests/fail/missing_namespace_attr.stderr new file mode 100644 index 000000000..074035d93 --- /dev/null +++ b/wp_derive_request_builder/tests/fail/missing_namespace_attr.stderr @@ -0,0 +1,5 @@ +error: Missing #[Namespace("_path_")] + --> tests/fail/missing_namespace_attr.rs:3:1 + | +3 | enum UsersRequest { + | ^^^^ diff --git a/wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.stderr b/wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.stderr deleted file mode 100644 index 266e307a2..000000000 --- a/wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Only a single #[SparseField(_field_type_)] attribute is supported - --> tests/fail/multiple_sparse_field_attr.rs:4:1 - | -4 | enum UsersRequest { - | ^^^^ diff --git a/wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.rs b/wp_derive_request_builder/tests/pass/external_outer_attr.rs similarity index 65% rename from wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.rs rename to wp_derive_request_builder/tests/pass/external_outer_attr.rs index 4d5613011..54e5839df 100644 --- a/wp_derive_request_builder/tests/fail/multiple_sparse_field_attr.rs +++ b/wp_derive_request_builder/tests/pass/external_outer_attr.rs @@ -1,7 +1,7 @@ -#[derive(wp_derive_request_builder::WpDerivedRequest)] +#[derive(wp_derive_request_builder::WpDerivedRequest, serde::Serialize)] #[Namespace("/wp/v2")] #[SparseField(crate::SparseUserField)] -#[SparseField(crate::SparsePluginField)] +#[serde(deny_unknown_fields)] enum UsersRequest { #[contextual_get(url = "/users", params = &UserListParams, output = Vec)] List, From c64df9e96bc1af1e6d2c7c45243120917df74511 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Fri, 5 Jul 2024 14:48:57 -0400 Subject: [PATCH 7/9] Improve outer attr parser for WpDerivedRequest --- wp_derive_request_builder/src/outer_attr.rs | 49 ++++++++----------- .../tests/fail/missing_namespace_attr.stderr | 2 +- .../fail/missing_sparse_field_attr.stderr | 2 +- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/wp_derive_request_builder/src/outer_attr.rs b/wp_derive_request_builder/src/outer_attr.rs index a87a2f4cd..8af9c7bf1 100644 --- a/wp_derive_request_builder/src/outer_attr.rs +++ b/wp_derive_request_builder/src/outer_attr.rs @@ -47,31 +47,28 @@ impl Parse for OuterAttr { fn parse(input: ParseStream) -> Result { let attrs = Attribute::parse_outer(input)?; - let (sparse_field, namespace) = attrs.into_iter().try_fold((None, None), |acc, a| { - let error_span = a.span(); - if let Meta::List(meta_list) = a.meta { - if meta_list.path.segments.len() != 1 { - Err(OuterAttrParseError::UnexpectedAttrPathSegmentCount - .into_syn_error(error_span)) - } else { - let s = meta_list - .path - .segments - .first() - .expect("Already verified that there is only one segment"); + let (sparse_field, namespace) = attrs.into_iter().fold((None, None), |(acc), a| { + let Meta::List(meta_list) = a.meta else { + return acc; + }; + if meta_list.path.segments.len() == 1 { + let s = meta_list + .path + .segments + .first() + .expect("Already verified that there is only one segment"); - match s.ident.to_string().as_str() { - "SparseField" => Ok((Some(meta_list.tokens), acc.1)), - "Namespace" => Ok((acc.0, Some(meta_list.tokens))), - // Unrecognized attribute may belong to another Derive macro, so we need - // to ignore and not return an error - _ => Ok(acc), - } + match s.ident.to_string().as_str() { + "SparseField" => (Some(meta_list.tokens), acc.1), + "Namespace" => (acc.0, Some(meta_list.tokens)), + // Unrecognized attributes may belong to another proc macro, so we need + // to ignore them and not return an error + _ => acc, } } else { - Err(OuterAttrParseError::WrongOuterAttrFormat.into_syn_error(error_span)) + acc } - })?; + }); let sparse_field_attr = sparse_field .map(|tokens| SparseFieldAttr { tokens }) .ok_or(OuterAttrParseError::MissingSparseFieldAttr.into_syn_error(input.span()))?; @@ -90,16 +87,12 @@ impl Parse for OuterAttr { pub enum OuterAttrParseError { #[error("Expecting #[Namespace(\"_path_\")] - Did you forget (\"\")?")] NamespaceAttrIsNotLiteral, - #[error("Expecting #[Namespace(\"_path_\")] - Found extra tokens")] + #[error("Expecting #[Namespace(\"_path_\")] - Path should be a single '/' separated literal")] NamespaceAttrHasMultipleTokens, - #[error("Missing #[Namespace(\"_path_\")]")] + #[error("Missing #[Namespace(\"_path_\")] attribute")] MissingNamespaceAttr, - #[error("Missing #[SparseField(_field_type_)]")] + #[error("Missing #[SparseField(_field_type_)] attribute")] MissingSparseFieldAttr, - #[error("Only SparseField & Namespace attributes only have one path segment")] - UnexpectedAttrPathSegmentCount, - #[error("Expecting #[SparseField(_field_type_)] & #[Namespace(\"_path_\")]")] - WrongOuterAttrFormat, #[error("Expecting #[Namespace(\"_path_\")]")] WrongNamespaceAttrFormat, } diff --git a/wp_derive_request_builder/tests/fail/missing_namespace_attr.stderr b/wp_derive_request_builder/tests/fail/missing_namespace_attr.stderr index 074035d93..22221cd69 100644 --- a/wp_derive_request_builder/tests/fail/missing_namespace_attr.stderr +++ b/wp_derive_request_builder/tests/fail/missing_namespace_attr.stderr @@ -1,4 +1,4 @@ -error: Missing #[Namespace("_path_")] +error: Missing #[Namespace("_path_")] attribute --> tests/fail/missing_namespace_attr.rs:3:1 | 3 | enum UsersRequest { diff --git a/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.stderr b/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.stderr index 4ab614797..dbf5de561 100644 --- a/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.stderr +++ b/wp_derive_request_builder/tests/fail/missing_sparse_field_attr.stderr @@ -1,4 +1,4 @@ -error: Missing #[SparseField(_field_type_)] +error: Missing #[SparseField(_field_type_)] attribute --> tests/fail/missing_sparse_field_attr.rs:3:1 | 3 | enum UsersRequest { From f702141f889a0d8bceedc48f26af4a4542cccff9 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Fri, 5 Jul 2024 15:28:17 -0400 Subject: [PATCH 8/9] Add error handling tests for namespace outer attr --- wp_derive_request_builder/src/outer_attr.rs | 39 +++++++++---------- .../namespace_attr_has_multiple_tokens.rs | 9 +++++ .../namespace_attr_has_multiple_tokens.stderr | 5 +++ .../fail/namespace_attr_has_no_tokens.rs | 9 +++++ .../fail/namespace_attr_has_no_tokens.stderr | 5 +++ .../fail/namespace_attr_is_not_literal.rs | 9 +++++ .../fail/namespace_attr_is_not_literal.stderr | 5 +++ 7 files changed, 61 insertions(+), 20 deletions(-) create mode 100644 wp_derive_request_builder/tests/fail/namespace_attr_has_multiple_tokens.rs create mode 100644 wp_derive_request_builder/tests/fail/namespace_attr_has_multiple_tokens.stderr create mode 100644 wp_derive_request_builder/tests/fail/namespace_attr_has_no_tokens.rs create mode 100644 wp_derive_request_builder/tests/fail/namespace_attr_has_no_tokens.stderr create mode 100644 wp_derive_request_builder/tests/fail/namespace_attr_is_not_literal.rs create mode 100644 wp_derive_request_builder/tests/fail/namespace_attr_is_not_literal.stderr diff --git a/wp_derive_request_builder/src/outer_attr.rs b/wp_derive_request_builder/src/outer_attr.rs index 8af9c7bf1..23a609582 100644 --- a/wp_derive_request_builder/src/outer_attr.rs +++ b/wp_derive_request_builder/src/outer_attr.rs @@ -1,4 +1,4 @@ -use proc_macro2::{Literal, TokenStream, TokenTree}; +use proc_macro2::{Literal, Span, TokenStream, TokenTree}; use syn::{ parse::{Parse, ParseStream}, spanned::Spanned, @@ -10,24 +10,20 @@ pub struct NamespaceAttr { pub token: TokenTree, } -impl TryFrom for NamespaceAttr { - type Error = OuterAttrParseError; - - fn try_from(value: TokenStream) -> std::result::Result { - let mut iter = value.into_iter(); +impl NamespaceAttr { + fn new(tokens: TokenStream, attr_span: Span) -> Result { + let tokens_span = tokens.span(); + let mut iter = tokens.into_iter(); if let Some(first) = iter.next() { if iter.next().is_some() { - // Has more than one token - Err(OuterAttrParseError::WrongNamespaceAttrFormat) + Err(OuterAttrParseError::NamespaceAttrHasMultipleTokens.into_syn_error(tokens_span)) } else if let TokenTree::Literal(_) = first { Ok(Self { token: first }) } else { - // Is not a literal - Err(OuterAttrParseError::NamespaceAttrIsNotLiteral) + Err(OuterAttrParseError::NamespaceAttrIsNotLiteral.into_syn_error(first.span())) } } else { - // Doesn't have any tokens - Err(OuterAttrParseError::WrongNamespaceAttrFormat) + Err(OuterAttrParseError::NamespaceAttrHasNoTokens.into_syn_error(attr_span)) } } } @@ -48,6 +44,7 @@ impl Parse for OuterAttr { let attrs = Attribute::parse_outer(input)?; let (sparse_field, namespace) = attrs.into_iter().fold((None, None), |(acc), a| { + let attr_span = a.span(); let Meta::List(meta_list) = a.meta else { return acc; }; @@ -59,8 +56,8 @@ impl Parse for OuterAttr { .expect("Already verified that there is only one segment"); match s.ident.to_string().as_str() { - "SparseField" => (Some(meta_list.tokens), acc.1), - "Namespace" => (acc.0, Some(meta_list.tokens)), + "SparseField" => (Some((meta_list.tokens, attr_span)), acc.1), + "Namespace" => (acc.0, Some((meta_list.tokens, attr_span))), // Unrecognized attributes may belong to another proc macro, so we need // to ignore them and not return an error _ => acc, @@ -70,11 +67,11 @@ impl Parse for OuterAttr { } }); let sparse_field_attr = sparse_field - .map(|tokens| SparseFieldAttr { tokens }) + .map(|(tokens, _)| SparseFieldAttr { tokens }) .ok_or(OuterAttrParseError::MissingSparseFieldAttr.into_syn_error(input.span()))?; let namespace_attr = namespace .ok_or(OuterAttrParseError::MissingNamespaceAttr.into_syn_error(input.span())) - .and_then(|t| NamespaceAttr::try_from(t).map_err(|e| e.into_syn_error(input.span())))?; + .and_then(|(t, attr_span)| NamespaceAttr::new(t, attr_span))?; Ok(Self { namespace_attr, @@ -85,16 +82,18 @@ impl Parse for OuterAttr { #[derive(Debug, thiserror::Error)] pub enum OuterAttrParseError { - #[error("Expecting #[Namespace(\"_path_\")] - Did you forget (\"\")?")] + #[error("Expecting #[Namespace(\"_path_\")] - Try wrapping the path in \"\"")] NamespaceAttrIsNotLiteral, - #[error("Expecting #[Namespace(\"_path_\")] - Path should be a single '/' separated literal")] + #[error( + "Expecting #[Namespace(\"_path_\")] - Path should be a single literal separated by '/'" + )] NamespaceAttrHasMultipleTokens, + #[error("Expecting #[Namespace(\"_path_\")] - Path is missing")] + NamespaceAttrHasNoTokens, #[error("Missing #[Namespace(\"_path_\")] attribute")] MissingNamespaceAttr, #[error("Missing #[SparseField(_field_type_)] attribute")] MissingSparseFieldAttr, - #[error("Expecting #[Namespace(\"_path_\")]")] - WrongNamespaceAttrFormat, } impl OuterAttrParseError { diff --git a/wp_derive_request_builder/tests/fail/namespace_attr_has_multiple_tokens.rs b/wp_derive_request_builder/tests/fail/namespace_attr_has_multiple_tokens.rs new file mode 100644 index 000000000..cde3a2a22 --- /dev/null +++ b/wp_derive_request_builder/tests/fail/namespace_attr_has_multiple_tokens.rs @@ -0,0 +1,9 @@ +#[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace("wp", "v2")] +#[SparseField(crate::SparseUserField)] +enum UsersRequest { + #[contextual_get(url = "/users", params = &UserListParams, output = Vec)] + List, +} + +fn main() {} diff --git a/wp_derive_request_builder/tests/fail/namespace_attr_has_multiple_tokens.stderr b/wp_derive_request_builder/tests/fail/namespace_attr_has_multiple_tokens.stderr new file mode 100644 index 000000000..e39c7d28b --- /dev/null +++ b/wp_derive_request_builder/tests/fail/namespace_attr_has_multiple_tokens.stderr @@ -0,0 +1,5 @@ +error: Expecting #[Namespace("_path_")] - Path should be a single literal separated by '/' + --> tests/fail/namespace_attr_has_multiple_tokens.rs:2:13 + | +2 | #[Namespace("wp", "v2")] + | ^^^^ diff --git a/wp_derive_request_builder/tests/fail/namespace_attr_has_no_tokens.rs b/wp_derive_request_builder/tests/fail/namespace_attr_has_no_tokens.rs new file mode 100644 index 000000000..06c629214 --- /dev/null +++ b/wp_derive_request_builder/tests/fail/namespace_attr_has_no_tokens.rs @@ -0,0 +1,9 @@ +#[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace()] +#[SparseField(crate::SparseUserField)] +enum UsersRequest { + #[contextual_get(url = "/users", params = &UserListParams, output = Vec)] + List, +} + +fn main() {} diff --git a/wp_derive_request_builder/tests/fail/namespace_attr_has_no_tokens.stderr b/wp_derive_request_builder/tests/fail/namespace_attr_has_no_tokens.stderr new file mode 100644 index 000000000..336776e9a --- /dev/null +++ b/wp_derive_request_builder/tests/fail/namespace_attr_has_no_tokens.stderr @@ -0,0 +1,5 @@ +error: Expecting #[Namespace("_path_")] - Path is missing + --> tests/fail/namespace_attr_has_no_tokens.rs:2:1 + | +2 | #[Namespace()] + | ^ diff --git a/wp_derive_request_builder/tests/fail/namespace_attr_is_not_literal.rs b/wp_derive_request_builder/tests/fail/namespace_attr_is_not_literal.rs new file mode 100644 index 000000000..0fc48418e --- /dev/null +++ b/wp_derive_request_builder/tests/fail/namespace_attr_is_not_literal.rs @@ -0,0 +1,9 @@ +#[derive(wp_derive_request_builder::WpDerivedRequest)] +#[Namespace(wp)] +#[SparseField(crate::SparseUserField)] +enum UsersRequest { + #[contextual_get(url = "/users", params = &UserListParams, output = Vec)] + List, +} + +fn main() {} diff --git a/wp_derive_request_builder/tests/fail/namespace_attr_is_not_literal.stderr b/wp_derive_request_builder/tests/fail/namespace_attr_is_not_literal.stderr new file mode 100644 index 000000000..c9d80e31f --- /dev/null +++ b/wp_derive_request_builder/tests/fail/namespace_attr_is_not_literal.stderr @@ -0,0 +1,5 @@ +error: Expecting #[Namespace("_path_")] - Try wrapping the path in "" + --> tests/fail/namespace_attr_is_not_literal.rs:2:13 + | +2 | #[Namespace(wp)] + | ^^ From 5fd3fd0636841b7fffb31b2d03e532d236cf8301 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Mon, 8 Jul 2024 12:56:00 -0400 Subject: [PATCH 9/9] Rename validate_endpoint unit test helper to validate_wp_v2_endpoint --- wp_api/src/request/endpoint.rs | 13 ++++++-- .../application_passwords_endpoint.rs | 26 ++++++++-------- .../src/request/endpoint/plugins_endpoint.rs | 20 ++++++------- wp_api/src/request/endpoint/users_endpoint.rs | 30 +++++++++---------- 4 files changed, 49 insertions(+), 40 deletions(-) diff --git a/wp_api/src/request/endpoint.rs b/wp_api/src/request/endpoint.rs index e2b9666e0..dc18e7e78 100644 --- a/wp_api/src/request/endpoint.rs +++ b/wp_api/src/request/endpoint.rs @@ -200,6 +200,12 @@ mod tests { .as_str(), format!("{}/bar/baz/quox", expected_wp_json_url) ); + assert_eq!( + api_base_url + .by_extending_and_splitting_by_forward_slash(["/bar", "/baz/quox"]) + .as_str(), + format!("{}/bar/baz/quox", expected_wp_json_url) + ); } fn wp_json_endpoint(base_url: &str) -> String { @@ -215,8 +221,11 @@ mod tests { ApiBaseUrl::try_from("https://example.com").unwrap().into() } - pub fn validate_endpoint(endpoint_url: ApiEndpointUrl, path: &str) { - let namespace = "/wp/v2"; + pub fn validate_wp_v2_endpoint(endpoint_url: ApiEndpointUrl, path: &str) { + validate_endpoint("/wp/v2", endpoint_url, path); + } + + fn validate_endpoint(namespace: &str, endpoint_url: ApiEndpointUrl, path: &str) { assert_eq!( endpoint_url.as_str(), format!("{}{}{}", fixture_api_base_url().as_str(), namespace, path) diff --git a/wp_api/src/request/endpoint/application_passwords_endpoint.rs b/wp_api/src/request/endpoint/application_passwords_endpoint.rs index 0eb04efa3..ece12bd8a 100644 --- a/wp_api/src/request/endpoint/application_passwords_endpoint.rs +++ b/wp_api/src/request/endpoint/application_passwords_endpoint.rs @@ -33,7 +33,7 @@ mod tests { use super::*; use crate::{ request::endpoint::{ - tests::{fixture_api_base_url, validate_endpoint}, + tests::{fixture_api_base_url, validate_wp_v2_endpoint}, ApiBaseUrl, }, WpContext, @@ -43,7 +43,7 @@ mod tests { #[rstest] fn create_application_password(endpoint: ApplicationPasswordsRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.create(&UserId(1)), "/users/1/application-passwords", ); @@ -51,7 +51,7 @@ mod tests { #[rstest] fn delete_single_application_password(endpoint: ApplicationPasswordsRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.delete( &UserId(2), &ApplicationPasswordUuid { @@ -64,7 +64,7 @@ mod tests { #[rstest] fn delete_all_application_passwords(endpoint: ApplicationPasswordsRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.delete_all(&UserId(1)), "/users/1/application-passwords", ); @@ -72,7 +72,7 @@ mod tests { #[rstest] fn list_application_passwords_with_edit_context(endpoint: ApplicationPasswordsRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.list_with_edit_context(&UserId(2)), "/users/2/application-passwords?context=edit", ); @@ -82,7 +82,7 @@ mod tests { fn list_application_passwords_with_embed_context( endpoint: ApplicationPasswordsRequestEndpoint, ) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.list_with_embed_context(&UserId(71)), "/users/71/application-passwords?context=embed", ); @@ -90,7 +90,7 @@ mod tests { #[rstest] fn list_application_passwords_with_view_context(endpoint: ApplicationPasswordsRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.list_with_view_context(&UserId(9999)), "/users/9999/application-passwords?context=view", ); @@ -105,7 +105,7 @@ mod tests { #[case] fields: &[SparseApplicationPasswordField], #[case] expected_path: &str, ) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.filter_list(&UserId(2), context, fields), expected_path, ); @@ -115,7 +115,7 @@ mod tests { fn retrieve_current_application_passwords_with_edit_context( endpoint: ApplicationPasswordsRequestEndpoint, ) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.retrieve_current_with_edit_context(&UserId(2)), "/users/2/application-passwords/introspect?context=edit", ); @@ -130,7 +130,7 @@ mod tests { #[case] fields: &[SparseApplicationPasswordField], #[case] expected_path: &str, ) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.filter_retrieve_current(&UserId(2), context, fields), expected_path, ); @@ -140,7 +140,7 @@ mod tests { fn retrieve_application_passwords_with_embed_context( endpoint: ApplicationPasswordsRequestEndpoint, ) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.retrieve_with_embed_context( &UserId(2), &ApplicationPasswordUuid { @@ -163,7 +163,7 @@ mod tests { let uuid = ApplicationPasswordUuid { uuid: "584a87d5-4f18-4c33-a315-4c05ed1fc485".to_string(), }; - validate_endpoint( + validate_wp_v2_endpoint( endpoint.filter_retrieve(&UserId(2), &uuid, context, fields), expected_path, ); @@ -171,7 +171,7 @@ mod tests { #[rstest] fn update_application_password(endpoint: ApplicationPasswordsRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.update( &UserId(2), &ApplicationPasswordUuid { diff --git a/wp_api/src/request/endpoint/plugins_endpoint.rs b/wp_api/src/request/endpoint/plugins_endpoint.rs index 44620358c..459574b90 100644 --- a/wp_api/src/request/endpoint/plugins_endpoint.rs +++ b/wp_api/src/request/endpoint/plugins_endpoint.rs @@ -27,7 +27,7 @@ mod tests { use crate::{ generate, request::endpoint::{ - tests::{fixture_api_base_url, validate_endpoint}, + tests::{fixture_api_base_url, validate_wp_v2_endpoint}, ApiBaseUrl, }, PluginStatus, WpContext, @@ -37,7 +37,7 @@ mod tests { #[rstest] fn create_plugin(endpoint: PluginsRequestEndpoint) { - validate_endpoint(endpoint.create(), "/plugins"); + validate_wp_v2_endpoint(endpoint.create(), "/plugins"); } #[rstest] @@ -53,7 +53,7 @@ mod tests { #[case] plugin_slug: PluginSlug, #[case] expected_path: &str, ) { - validate_endpoint(endpoint.delete(&plugin_slug), expected_path); + validate_wp_v2_endpoint(endpoint.delete(&plugin_slug), expected_path); } #[rstest] @@ -66,7 +66,7 @@ mod tests { #[case] params: PluginListParams, #[case] expected_path: &str, ) { - validate_endpoint(endpoint.list_with_edit_context(¶ms), expected_path); + validate_wp_v2_endpoint(endpoint.list_with_edit_context(¶ms), expected_path); } #[rstest] @@ -77,7 +77,7 @@ mod tests { #[case] params: PluginListParams, #[case] expected_path: &str, ) { - validate_endpoint(endpoint.list_with_embed_context(¶ms), expected_path); + validate_wp_v2_endpoint(endpoint.list_with_embed_context(¶ms), expected_path); } #[rstest] @@ -88,7 +88,7 @@ mod tests { #[case] params: PluginListParams, #[case] expected_path: &str, ) { - validate_endpoint(endpoint.list_with_view_context(¶ms), expected_path); + validate_wp_v2_endpoint(endpoint.list_with_view_context(¶ms), expected_path); } #[rstest] @@ -124,7 +124,7 @@ mod tests { #[case] fields: &[SparsePluginField], #[case] expected_path: &str, ) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.filter_list(context, ¶ms, fields), expected_path, ); @@ -149,7 +149,7 @@ mod tests { #[case] plugin_slug: PluginSlug, #[case] expected_path: &str, ) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.retrieve_with_view_context(&plugin_slug), expected_path, ); @@ -187,7 +187,7 @@ mod tests { #[case] fields: &[SparsePluginField], #[case] expected_path: &str, ) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.filter_retrieve(&plugin_slug, context, fields), expected_path, ); @@ -206,7 +206,7 @@ mod tests { #[case] plugin_slug: PluginSlug, #[case] expected_path: &str, ) { - validate_endpoint(endpoint.update(&plugin_slug), expected_path); + validate_wp_v2_endpoint(endpoint.update(&plugin_slug), expected_path); } #[fixture] diff --git a/wp_api/src/request/endpoint/users_endpoint.rs b/wp_api/src/request/endpoint/users_endpoint.rs index 3c4dd25bb..5ea6ad736 100644 --- a/wp_api/src/request/endpoint/users_endpoint.rs +++ b/wp_api/src/request/endpoint/users_endpoint.rs @@ -32,7 +32,7 @@ mod tests { use super::*; use crate::{ request::endpoint::{ - tests::{fixture_api_base_url, validate_endpoint}, + tests::{fixture_api_base_url, validate_wp_v2_endpoint}, ApiBaseUrl, }, WpApiParamUsersHasPublishedPosts, WpContext, @@ -42,12 +42,12 @@ mod tests { #[rstest] fn create_user(endpoint: UsersRequestEndpoint) { - validate_endpoint(endpoint.create(), "/users"); + validate_wp_v2_endpoint(endpoint.create(), "/users"); } #[rstest] fn delete_user(endpoint: UsersRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.delete( &UserId(54), &UserDeleteParams { @@ -60,7 +60,7 @@ mod tests { #[rstest] fn delete_current_user(endpoint: UsersRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.delete_me(&UserDeleteParams { reassign: UserId(98), }), @@ -70,7 +70,7 @@ mod tests { #[rstest] fn list_users(endpoint: UsersRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.list_with_edit_context(&UserListParams::default()), "/users?context=edit", ); @@ -78,7 +78,7 @@ mod tests { #[rstest] fn list_users_default_params_empty_fields(endpoint: UsersRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.list_with_edit_context(&UserListParams::default()), "/users?context=edit", ); @@ -101,7 +101,7 @@ mod tests { who: None, has_published_posts: Some(WpApiParamUsersHasPublishedPosts::True), }; - validate_endpoint( + validate_wp_v2_endpoint( endpoint.list_with_edit_context(¶ms), "/users?context=edit&page=2&per_page=60&search=foo&slug=bar%2Cbaz&has_published_posts=true", ); @@ -109,7 +109,7 @@ mod tests { #[rstest] fn filter_list_users_default_params_empty_fields(endpoint: UsersRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.filter_list(WpContext::Edit, &UserListParams::default(), &[]), "/users?context=edit&_fields=", ); @@ -135,7 +135,7 @@ mod tests { "page".to_string(), ])), }; - validate_endpoint( + validate_wp_v2_endpoint( endpoint.filter_list(WpContext::Edit, ¶ms, &[SparseUserField::Name, SparseUserField::Email]), "/users?context=edit&page=2&per_page=60&search=foo&slug=bar%2Cbaz&has_published_posts=post%2Cpage&_fields=name%2Cemail", ); @@ -143,7 +143,7 @@ mod tests { #[rstest] fn retrieve_user(endpoint: UsersRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.retrieve_with_view_context(&UserId(98)), "/users/98?context=view", ); @@ -151,7 +151,7 @@ mod tests { #[rstest] fn filter_retrieve_user(endpoint: UsersRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.filter_retrieve( &UserId(98), WpContext::View, @@ -163,7 +163,7 @@ mod tests { #[rstest] fn retrieve_current_user(endpoint: UsersRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.retrieve_me_with_embed_context(), "/users/me?context=embed", ); @@ -171,7 +171,7 @@ mod tests { #[rstest] fn filter_retrieve_current_user(endpoint: UsersRequestEndpoint) { - validate_endpoint( + validate_wp_v2_endpoint( endpoint.filter_retrieve_me( WpContext::Embed, &[SparseUserField::Roles, SparseUserField::Capabilities], @@ -182,12 +182,12 @@ mod tests { #[rstest] fn update_user(endpoint: UsersRequestEndpoint) { - validate_endpoint(endpoint.update(&UserId(98)), "/users/98"); + validate_wp_v2_endpoint(endpoint.update(&UserId(98)), "/users/98"); } #[rstest] fn update_current_user(endpoint: UsersRequestEndpoint) { - validate_endpoint(endpoint.update_me(), "/users/me"); + validate_wp_v2_endpoint(endpoint.update_me(), "/users/me"); } #[fixture]