Skip to content

Conversation

oguzkocer
Copy link
Contributor

Following up on #149, this PR adds request builder generation to #[derive(WpDerivedRequest)]. Besides the new fn_body_build_request_from_url helper, it doesn't require any new implementation and can be built from the existing helpers - mostly because the existing helpers were built to support this type alongside the endpoint generation.

It adds a new WpApiRequestBuilder type. This is a temporary type that can be used to make manual requests. It takes a request executor, but doesn't actually use it. Once we re-organize RequestBuilder type, we'll be able to address this, but for now, it's added to be used in wp_api/tests/test_manual_request_builder_immut.rs. These new tests prove that requests can be built from the generated type and executed in the same way we used to do it before the RequestExecutor trait.

Please keep in mind that it's not possible to have everything be in polished state in this transition period - unless we want to do all the changes in a huge PR. That's why for example the new generated type is named UsersRequestBuilder2. If we were to use the actual name, it'll clash with the existing type - even though it's in a separate module - because the type is exposed through FFI. I'll do my best to address these TODOs once everything is in place.


To Test

  • make test-server && make dump-mysql && make backup-wp-content-plugins
  • cargo test --test '*' -- --test-threads 1

Here is an example usage and its generated code:

#[derive(wp_derive_request_builder::WpDerivedRequest)]
#[SparseField(SparseUserField)]
enum UsersRequest {
    #[contextual_get(url = "/users", params = &UserListParams, output = Vec<crate::SparseUser>)]
    List,
    #[post(url = "/users", params = &crate::UserCreateParams, output = UserWithEditContext)]
    Create,
    #[delete(url = "/users/<user_id>", params = &UserDeleteParams, output = crate::UserDeleteResponse)]
    Delete,
    #[delete(url = "/users/me", params = &UserDeleteParams, output = crate::UserDeleteResponse)]
    DeleteMe,
    #[contextual_get(url = "/users/<user_id>", output = crate::SparseUser)]
    Retrieve,
    #[contextual_get(url = "/users/me", output = crate::SparseUser)]
    RetrieveMe,
    #[post(url = "/users/<user_id>", params = &crate::UserUpdateParams, output = UserWithEditContext)]
    Update,
    #[post(url = "/users/me", params = &crate::UserUpdateParams, output = UserWithEditContext)]
    UpdateMe,
}
#[derive(Debug, uniffi::Object)]
pub struct UsersRequestBuilder2 {
    endpoint: UsersRequestEndpoint,
    request_builder: std::sync::Arc<crate::request::RequestBuilder>,
}
impl UsersRequestBuilder2 {
    pub(crate) fn new(
        api_base_url: std::sync::Arc<crate::request::endpoint::ApiBaseUrl>,
        request_builder: std::sync::Arc<crate::request::RequestBuilder>,
    ) -> Self {
        Self {
            endpoint: UsersRequestEndpoint::new(api_base_url),
            request_builder,
        }
    }
}
#[uniffi::export]
impl UsersRequestBuilder2 {
    pub fn list_with_edit_context(
        &self,
        params: &UserListParams,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.list_with_edit_context(params);
        self.request_builder.build_get_request(url)
    }
    pub fn list_with_embed_context(
        &self,
        params: &UserListParams,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.list_with_embed_context(params);
        self.request_builder.build_get_request(url)
    }
    pub fn list_with_view_context(
        &self,
        params: &UserListParams,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.list_with_view_context(params);
        self.request_builder.build_get_request(url)
    }
    pub fn filter_list(
        &self,
        context: WpContext,
        params: &UserListParams,
        fields: &[SparseUserField],
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.filter_list(context, params, fields);
        self.request_builder.build_get_request(url)
    }
    pub fn create(
        &self,
        params: &crate::UserCreateParams,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.create();
        self.request_builder.build_post_request(url, params)
    }
    pub fn filter_create(
        &self,
        params: &crate::UserCreateParams,
        fields: &[SparseUserField],
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.filter_create(fields);
        self.request_builder.build_post_request(url, params)
    }
    pub fn delete(
        &self,
        user_id: UserId,
        params: &UserDeleteParams,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.delete(user_id, params);
        self.request_builder.build_delete_request(url)
    }
    pub fn filter_delete(
        &self,
        user_id: UserId,
        params: &UserDeleteParams,
        fields: &[SparseUserField],
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.filter_delete(user_id, params, fields);
        self.request_builder.build_delete_request(url)
    }
    pub fn delete_me(
        &self,
        params: &UserDeleteParams,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.delete_me(params);
        self.request_builder.build_delete_request(url)
    }
    pub fn filter_delete_me(
        &self,
        params: &UserDeleteParams,
        fields: &[SparseUserField],
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.filter_delete_me(params, fields);
        self.request_builder.build_delete_request(url)
    }
    pub fn retrieve_with_edit_context(
        &self,
        user_id: UserId,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.retrieve_with_edit_context(user_id);
        self.request_builder.build_get_request(url)
    }
    pub fn retrieve_with_embed_context(
        &self,
        user_id: UserId,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.retrieve_with_embed_context(user_id);
        self.request_builder.build_get_request(url)
    }
    pub fn retrieve_with_view_context(
        &self,
        user_id: UserId,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.retrieve_with_view_context(user_id);
        self.request_builder.build_get_request(url)
    }
    pub fn filter_retrieve(
        &self,
        user_id: UserId,
        context: WpContext,
        fields: &[SparseUserField],
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.filter_retrieve(user_id, context, fields);
        self.request_builder.build_get_request(url)
    }
    pub fn retrieve_me_with_edit_context(&self) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.retrieve_me_with_edit_context();
        self.request_builder.build_get_request(url)
    }
    pub fn retrieve_me_with_embed_context(
        &self,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.retrieve_me_with_embed_context();
        self.request_builder.build_get_request(url)
    }
    pub fn retrieve_me_with_view_context(&self) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.retrieve_me_with_view_context();
        self.request_builder.build_get_request(url)
    }
    pub fn filter_retrieve_me(
        &self,
        context: WpContext,
        fields: &[SparseUserField],
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.filter_retrieve_me(context, fields);
        self.request_builder.build_get_request(url)
    }
    pub fn update(
        &self,
        user_id: UserId,
        params: &crate::UserUpdateParams,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.update(user_id);
        self.request_builder.build_post_request(url, params)
    }
    pub fn filter_update(
        &self,
        user_id: UserId,
        params: &crate::UserUpdateParams,
        fields: &[SparseUserField],
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.filter_update(user_id, fields);
        self.request_builder.build_post_request(url, params)
    }
    pub fn update_me(
        &self,
        params: &crate::UserUpdateParams,
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.update_me();
        self.request_builder.build_post_request(url, params)
    }
    pub fn filter_update_me(
        &self,
        params: &crate::UserUpdateParams,
        fields: &[SparseUserField],
    ) -> crate::request::WpNetworkRequest {
        let url = self.endpoint.filter_update_me(fields);
        self.request_builder.build_post_request(url, params)
    }
}

@oguzkocer oguzkocer added the Rust label Jun 20, 2024
@oguzkocer oguzkocer added this to the 0.1 milestone Jun 20, 2024
@oguzkocer oguzkocer requested a review from jkmassel June 20, 2024 19:34
@oguzkocer oguzkocer enabled auto-merge (squash) June 20, 2024 19:54
@oguzkocer oguzkocer merged commit cdc36a6 into trunk Jun 20, 2024
@oguzkocer oguzkocer deleted the wp_derived_request_generate_request_builder branch June 20, 2024 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants