diff --git a/native/kotlin/api/kotlin/src/integrationTest/kotlin/PostTypesEndpointTest.kt b/native/kotlin/api/kotlin/src/integrationTest/kotlin/PostTypesEndpointTest.kt index f954e8037..201d653f4 100644 --- a/native/kotlin/api/kotlin/src/integrationTest/kotlin/PostTypesEndpointTest.kt +++ b/native/kotlin/api/kotlin/src/integrationTest/kotlin/PostTypesEndpointTest.kt @@ -26,7 +26,7 @@ class PostTypesEndpointTest { val postTypesPost = client.request { requestBuilder -> requestBuilder.postTypes().retrieveWithEditContext(PostType.Post) }.assertSuccessAndRetrieveData().data - assert(postTypesPost.supports.map[PostTypeSupports.Title]!!) + assert(postTypesPost.supports.map[PostTypeSupports.Title]!!.asJsonBool()!!) assertFalse(postTypesPost.capabilities[PostTypeCapabilities.EditPosts]!!.isEmpty()) } diff --git a/wp_api/src/post_types.rs b/wp_api/src/post_types.rs index b905d5c50..d8fc6cf31 100644 --- a/wp_api/src/post_types.rs +++ b/wp_api/src/post_types.rs @@ -1,7 +1,8 @@ -use crate::impl_as_query_value_from_to_string; +use crate::{JsonValue, impl_as_query_value_from_to_string}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::str::FromStr; +use std::sync::Arc; use wp_contextual::WpContextual; use wp_serde_helper::deserialize_empty_array_or_hashmap; @@ -97,7 +98,50 @@ pub struct PostTypeSupportsMap { #[serde(deserialize_with = "deserialize_empty_array_or_hashmap")] #[serde(flatten)] #[serde(rename = "supports")] - pub map: HashMap, + pub map: HashMap>, +} + +impl PostTypeSupportsMap { + /// Check if the post type supports a specific feature by checking if the key is present. + /// + /// Note: This only checks for key presence, not the associated value. WordPress typically + /// includes a feature in the map with a `true` value when supported, and omits it entirely + /// when not supported. The value can also be an object with additional configuration (e.g., + /// `editor` may have nested settings). We assume that if a key is present, the feature is + /// supported, regardless of the actual value. + pub fn supports(&self, feature: &PostTypeSupports) -> bool { + self.map.contains_key(feature) + } +} + +/// Check if a post type supports a specific feature by checking if the key is present. +/// +/// Note: This only checks for key presence, not the associated value. See +/// `PostTypeSupportsMap::supports` for details on this assumption. +#[uniffi::export] +fn post_type_supports(supports_map: &PostTypeSupportsMap, feature: PostTypeSupports) -> bool { + supports_map.supports(&feature) +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, uniffi::Object)] +#[serde(transparent)] +pub struct PostTypeSupportsValue { + #[serde(flatten)] + pub json_value: JsonValue, +} + +#[uniffi::export] +impl PostTypeSupportsValue { + fn as_json_value(&self) -> JsonValue { + self.json_value.clone() + } + + pub fn as_json_bool(&self) -> Option { + match self.json_value { + JsonValue::Bool(b) => Some(b), + _ => None, + } + } } #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, uniffi::Record)] diff --git a/wp_api_integration_tests/tests/test_post_types_immut.rs b/wp_api_integration_tests/tests/test_post_types_immut.rs index 140cba347..7c142acf8 100644 --- a/wp_api_integration_tests/tests/test_post_types_immut.rs +++ b/wp_api_integration_tests/tests/test_post_types_immut.rs @@ -93,8 +93,12 @@ async fn retrieve_post_types_with_edit_context( // post types might not support `Title` in which case it's perfectly fine to completely // remove this assertion. assert_eq!( - post_type.supports.map.get(&PostTypeSupports::Title), - Some(true).as_ref() + post_type + .supports + .map + .get(&PostTypeSupports::Title) + .and_then(|v| v.as_json_bool()), + Some(true) ); // All post types in our current testing sites have `EditPost` capability, so we use this // assertion to verify that we are able to parse `capabilities` field properly.