Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate async request executor type for #[derive(WpDerivedRequest)] #153

Merged
merged 5 commits into from
Jun 20, 2024

Conversation

oguzkocer
Copy link
Contributor

@oguzkocer oguzkocer commented Jun 20, 2024

Following up on #149 & #151, this PR adds request async request executor generation to #[derive(WpDerivedRequest)].

This type uses the the request builder added in #151 and a request executor to make the requests and then parse it. The return type is figured out from the given output type. For post & delete requests, the return type is the same as the given output type. For contextual_get requests, the type is calculated by replacing Sparse prefix with the {}With{}Context format, except for filter functions.

The PR removes the RequestType::Get and the get attribute from WpDerivedRequest. We currently don't have any non-contextual get requests and I think it's unlikely that we'll have any - at least for the foreseeable future. Since we don't exactly know what those requests look like, it's risky to implement it with just our assumptions. I figured removing it until we at least have one regular get request was the safer choice.

Known issues: #152, #154

Due to #154, I've decided to disable generating filter functions for post & delete requests in 75d0814. This is not a functionality we currently have in trunk and even if the issue is tracked, I think it might be risky to produce incorrect code. We can easily re-enable it once we work out how to handle the issue, but at least #154 won't be an urgent issue anymore considering it's very low impact.


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 = crate::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 = crate::UserWithEditContext)]
    Update,
    #[post(url = "/users/me", params = &crate::UserUpdateParams, output = crate::UserWithEditContext)]
    UpdateMe,
}
#[derive(Debug, uniffi::Object)]
pub struct UsersRequestExecutor {
    request_builder: UsersRequestBuilder2,
    request_executor: std::sync::Arc<dyn crate::request::RequestExecutor>,
}
impl UsersRequestExecutor {
    pub(crate) fn new(
        request_builder: UsersRequestBuilder2,
        request_executor: std::sync::Arc<dyn crate::request::RequestExecutor>,
    ) -> Self {
        Self {
            request_builder,
            request_executor,
        }
    }
}
#[uniffi::export]
impl UsersRequestExecutor {
    pub async fn list_with_edit_context(
        &self,
        params: &UserListParams,
    ) -> Result<Vec<crate::UserWithEditContext>, crate::WpApiError> {
        let request = self.request_builder.list_with_edit_context(params);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn list_with_embed_context(
        &self,
        params: &UserListParams,
    ) -> Result<Vec<crate::UserWithEmbedContext>, crate::WpApiError> {
        let request = self.request_builder.list_with_embed_context(params);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn list_with_view_context(
        &self,
        params: &UserListParams,
    ) -> Result<Vec<crate::UserWithViewContext>, crate::WpApiError> {
        let request = self.request_builder.list_with_view_context(params);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn filter_list(
        &self,
        context: WpContext,
        params: &UserListParams,
        fields: &[SparseUserField],
    ) -> Result<Vec<crate::SparseUser>, crate::WpApiError> {
        let request = self.request_builder.filter_list(context, params, fields);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn create(
        &self,
        params: &crate::UserCreateParams,
    ) -> Result<crate::UserWithEditContext, crate::WpApiError> {
        let request = self.request_builder.create(params);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn delete(
        &self,
        user_id: UserId,
        params: &UserDeleteParams,
    ) -> Result<crate::UserDeleteResponse, crate::WpApiError> {
        let request = self.request_builder.delete(user_id, params);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn delete_me(
        &self,
        params: &UserDeleteParams,
    ) -> Result<crate::UserDeleteResponse, crate::WpApiError> {
        let request = self.request_builder.delete_me(params);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn retrieve_with_edit_context(
        &self,
        user_id: UserId,
    ) -> Result<crate::UserWithEditContext, crate::WpApiError> {
        let request = self.request_builder.retrieve_with_edit_context(user_id);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn retrieve_with_embed_context(
        &self,
        user_id: UserId,
    ) -> Result<crate::UserWithEmbedContext, crate::WpApiError> {
        let request = self.request_builder.retrieve_with_embed_context(user_id);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn retrieve_with_view_context(
        &self,
        user_id: UserId,
    ) -> Result<crate::UserWithViewContext, crate::WpApiError> {
        let request = self.request_builder.retrieve_with_view_context(user_id);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn filter_retrieve(
        &self,
        user_id: UserId,
        context: WpContext,
        fields: &[SparseUserField],
    ) -> Result<crate::SparseUser, crate::WpApiError> {
        let request = self.request_builder.filter_retrieve(user_id, context, fields);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn retrieve_me_with_edit_context(
        &self,
    ) -> Result<crate::UserWithEditContext, crate::WpApiError> {
        let request = self.request_builder.retrieve_me_with_edit_context();
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn retrieve_me_with_embed_context(
        &self,
    ) -> Result<crate::UserWithEmbedContext, crate::WpApiError> {
        let request = self.request_builder.retrieve_me_with_embed_context();
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn retrieve_me_with_view_context(
        &self,
    ) -> Result<crate::UserWithViewContext, crate::WpApiError> {
        let request = self.request_builder.retrieve_me_with_view_context();
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn filter_retrieve_me(
        &self,
        context: WpContext,
        fields: &[SparseUserField],
    ) -> Result<crate::SparseUser, crate::WpApiError> {
        let request = self.request_builder.filter_retrieve_me(context, fields);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn update(
        &self,
        user_id: UserId,
        params: &crate::UserUpdateParams,
    ) -> Result<crate::UserWithEditContext, crate::WpApiError> {
        let request = self.request_builder.update(user_id, params);
        self.request_executor.execute(request).await?.parse()
    }
    pub async fn update_me(
        &self,
        params: &crate::UserUpdateParams,
    ) -> Result<crate::UserWithEditContext, crate::WpApiError> {
        let request = self.request_builder.update_me(params);
        self.request_executor.execute(request).await?.parse()
    }
}

@oguzkocer oguzkocer added the Rust label Jun 20, 2024
@oguzkocer oguzkocer added this to the 0.1 milestone Jun 20, 2024
@oguzkocer oguzkocer force-pushed the wp_derived_request_generate_async_request_executor branch from 9c207c7 to 44d8359 Compare June 20, 2024 21:34
@oguzkocer oguzkocer marked this pull request as ready for review June 20, 2024 21:54
@oguzkocer oguzkocer requested a review from jkmassel June 20, 2024 21:54
@oguzkocer oguzkocer enabled auto-merge (squash) June 20, 2024 21:55
@oguzkocer oguzkocer merged commit 56bd9df into trunk Jun 20, 2024
24 checks passed
@oguzkocer oguzkocer deleted the wp_derived_request_generate_async_request_executor branch June 20, 2024 22:13
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