Skip to content

Commit 56f6562

Browse files
committed
Parse additional data in WP.com comments API
1 parent f34ebee commit 56f6562

File tree

7 files changed

+134
-8
lines changed

7 files changed

+134
-8
lines changed

wp_api/src/comments.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
JsonValue, UserAvatarSize, UserId, WpApiParamOrder, WpResponseString,
2+
AnyJson, UserAvatarSize, UserId, WpApiParamOrder, WpResponseString,
33
date::WpGmtDateTime,
44
impl_as_query_value_for_new_type, impl_as_query_value_from_to_string,
55
posts::PostId,
@@ -8,7 +8,7 @@ use crate::{
88
},
99
};
1010
use serde::{Deserialize, Serialize};
11-
use std::{collections::HashMap, num::ParseIntError, str::FromStr};
11+
use std::{collections::HashMap, num::ParseIntError, str::FromStr, sync::Arc};
1212
use strum_macros::IntoStaticStr;
1313
use wp_contextual::WpContextual;
1414

@@ -530,7 +530,7 @@ pub struct SparseComment {
530530
pub author_avatar_urls: Option<HashMap<UserAvatarSize, WpResponseString>>,
531531
#[serde(flatten)]
532532
#[WpContext(edit, embed, view)]
533-
pub extras: Option<JsonValue>,
533+
pub additional_fields: Option<Arc<AnyJson>>,
534534
// meta field is omitted for now: https://github.com/Automattic/wordpress-rs/issues/422
535535
}
536536

wp_api/src/lib.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use plugins::*;
22
use serde::{Deserialize, Serialize};
3+
use serde_json::Value;
34
use std::collections::HashMap;
45
use users::*;
56
use wp_localization::{MessageBundle, WpMessages, WpSupportsLocalization};
@@ -118,6 +119,14 @@ pub enum JsonValue {
118119
Object(HashMap<String, JsonValue>),
119120
}
120121

122+
/// Similar to `JsonValue`, but exported as a Uniffi object.
123+
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, uniffi::Object)]
124+
#[uniffi::export(Eq, Hash)]
125+
pub struct AnyJson {
126+
#[serde(flatten)]
127+
pub raw: Value,
128+
}
129+
121130
uniffi::custom_newtype!(WpResponseString, Option<String>);
122131
#[derive(Debug, Serialize, Deserialize)]
123132
#[serde(try_from = "BoolOrString")]
@@ -235,4 +244,30 @@ mod tests {
235244
fn test_orderby_string_conversion(#[case] orderby: WpApiParamOrder) {
236245
assert_eq!(orderby, orderby.to_string().parse().unwrap());
237246
}
247+
248+
#[derive(Deserialize, Debug)]
249+
struct Person {
250+
name: String,
251+
#[serde(flatten)]
252+
other_fields: AnyJson,
253+
}
254+
255+
#[test]
256+
fn test_parse_any_json() {
257+
let json = r#"{"name": "Alice", "age": 30, "city": "Wonderland"}"#;
258+
let person: Person = serde_json::from_str(json).unwrap();
259+
assert_eq!(person.name, "Alice");
260+
assert_eq!(
261+
person.other_fields.raw,
262+
serde_json::json!({"age": 30, "city": "Wonderland"})
263+
);
264+
}
265+
266+
#[test]
267+
fn test_parse_empty_any_json() {
268+
let json = r#"{"name": "Alice"}"#;
269+
let person: Person = serde_json::from_str(json).unwrap();
270+
assert_eq!(person.name, "Alice");
271+
assert_eq!(person.other_fields.raw, serde_json::json!({}));
272+
}
238273
}

wp_api/src/uniffi_serde.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use wp_localization::{MessageBundle, WpMessages, WpSupportsLocalization};
22
use wp_localization_macro::WpDeriveLocalizable;
33

44
#[derive(Debug, thiserror::Error, uniffi::Error, WpDeriveLocalizable)]
5-
pub(crate) enum UniffiSerializationError {
5+
pub enum UniffiSerializationError {
66
Serde { reason: String },
77
}
88

wp_api/src/wp_com/endpoint.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
use std::sync::Arc;
77
use strum::IntoEnumIterator;
88

9+
pub mod extensions;
910
pub mod followers_endpoint;
1011
pub mod jetpack_connection_endpoint;
1112
pub mod oauth2;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use serde::Deserialize;
2+
3+
use crate::{AnyJson, uniffi_serde::UniffiSerializationError};
4+
5+
#[derive(Debug, Deserialize, uniffi::Record)]
6+
pub struct WpComCommentExtension {
7+
#[serde(rename = "extended_post")]
8+
pub post: Option<WpComCommentExtensionPostInfo>,
9+
#[serde(rename = "extended_i_replied")]
10+
pub i_replied: bool,
11+
#[serde(rename = "extended_like_count")]
12+
pub like_count: u32,
13+
#[serde(rename = "extended_i_like")]
14+
pub i_like: bool,
15+
}
16+
17+
#[derive(Debug, Deserialize, uniffi::Record)]
18+
pub struct WpComCommentExtensionPostInfo {
19+
pub id: u64,
20+
pub title: String,
21+
#[serde(rename = "type")]
22+
pub kind: String,
23+
pub link: String,
24+
}
25+
26+
#[uniffi::export(with_foreign)]
27+
pub trait WpComCommentExtensionProvider: Send + Sync {
28+
fn parse_extension(&self) -> Result<WpComCommentExtension, UniffiSerializationError>;
29+
}
30+
31+
#[uniffi::export]
32+
impl WpComCommentExtensionProvider for AnyJson {
33+
fn parse_extension(&self) -> Result<WpComCommentExtension, UniffiSerializationError> {
34+
serde_json::to_string(&self.raw)
35+
.and_then(|json| serde_json::from_str(&json))
36+
.map_err(Into::into)
37+
}
38+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod comments;

wp_api_integration_tests/tests/test_comments_immut.rs

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
use serde_json::Value;
12
use wp_api::{
2-
JsonValue,
33
comments::{
44
CommentId, CommentListParams, CommentRetrieveParams, CommentStatus, CommentType,
55
SparseCommentFieldWithEditContext, SparseCommentFieldWithEmbedContext,
66
SparseCommentFieldWithViewContext, WpApiParamCommentsOrderBy,
77
},
88
posts::PostId,
99
users::UserAvatarSize,
10+
wp_com::{WpComBaseUrl, endpoint::WpComDotOrgApiUrlResolver},
1011
};
11-
use wp_api_integration_tests::prelude::*;
12+
use wp_api_integration_tests::{WpComTestCredentials, prelude::*};
1213

1314
#[tokio::test]
1415
#[apply(list_cases)]
@@ -217,14 +218,64 @@ async fn parse_extras() {
217218
.await
218219
.assert_response()
219220
.data;
220-
match comment.extras {
221-
JsonValue::Object(ref map) => {
221+
match comment.additional_fields.raw {
222+
Value::Object(ref map) => {
222223
assert!(map.contains_key("_links"));
223224
}
224225
_ => panic!("Expected extras to be an object"),
225226
}
226227
}
227228

229+
#[tokio::test]
230+
#[parallel]
231+
#[ignore]
232+
async fn wpcom_comment_extension() {
233+
// You'll need to replace the site ID and comment ID with valid ones.
234+
let site_id = "site_id".to_string();
235+
let comment_id = CommentId(2);
236+
let client = WpApiClient::new(
237+
Arc::new(WpComDotOrgApiUrlResolver::new(
238+
site_id,
239+
WpComBaseUrl::Production,
240+
)),
241+
WpApiClientDelegate {
242+
auth_provider: Arc::new(WpAuthenticationProvider::static_with_auth(
243+
WpAuthentication::Bearer {
244+
token: WpComTestCredentials::instance().bearer_token.to_string(),
245+
},
246+
)),
247+
request_executor: Arc::new(ReqwestRequestExecutor::default()),
248+
middleware_pipeline: Arc::new(WpApiMiddlewarePipeline::default()),
249+
app_notifier: Arc::new(EmptyAppNotifier),
250+
},
251+
);
252+
use wp_api::wp_com::endpoint::extensions::comments::WpComCommentExtensionProvider;
253+
254+
let comment = client
255+
.comments()
256+
.retrieve_with_view_context(&comment_id, &CommentRetrieveParams::default())
257+
.await
258+
.assert_response()
259+
.data;
260+
assert!(comment.additional_fields.parse_extension().is_ok());
261+
262+
let comment = client
263+
.comments()
264+
.retrieve_with_edit_context(&comment_id, &CommentRetrieveParams::default())
265+
.await
266+
.assert_response()
267+
.data;
268+
assert!(comment.additional_fields.parse_extension().is_ok());
269+
270+
let comment = client
271+
.comments()
272+
.retrieve_with_embed_context(&comment_id, &CommentRetrieveParams::default())
273+
.await
274+
.assert_response()
275+
.data;
276+
assert!(comment.additional_fields.parse_extension().is_ok());
277+
}
278+
228279
#[template]
229280
#[rstest]
230281
#[case::default(CommentListParams::default())]

0 commit comments

Comments
 (0)