@@ -90,7 +90,7 @@ pub struct SupportAttachment {
9090 pub content_type : String ,
9191 pub size : u64 ,
9292 pub url : String ,
93- pub metadata : HashMap < String , AttachmentMetadataValue > ,
93+ pub metadata : HashMap < AttachmentMetadataKey , AttachmentMetadataValue > ,
9494}
9595
9696#[ derive( Debug , PartialEq , Eq , Serialize , Deserialize , uniffi:: Enum ) ]
@@ -100,12 +100,25 @@ pub enum SupportMessageAuthor {
100100 SupportAgent ( SupportAgentIdentity ) ,
101101}
102102
103- #[ derive( Debug , PartialEq , Eq , Serialize , Deserialize , uniffi:: Enum , strum_macros:: Display ) ]
104- #[ strum( serialize_all = "snake_case" ) ]
103+ #[ derive(
104+ Debug ,
105+ Hash ,
106+ PartialEq ,
107+ Eq ,
108+ Serialize ,
109+ Deserialize ,
110+ uniffi:: Enum ,
111+ strum_macros:: Display ,
112+ strum_macros:: EnumString ,
113+ ) ]
105114pub enum AttachmentMetadataKey {
115+ #[ serde( alias = "width" ) ]
106116 Width ,
117+ #[ serde( alias = "height" ) ]
107118 Height ,
108- Other ( String ) ,
119+ #[ serde( untagged) ]
120+ #[ strum( default ) ]
121+ Custom ( String ) ,
109122}
110123
111124#[ derive( Debug , PartialEq , Eq , Serialize , Deserialize , uniffi:: Enum ) ]
@@ -116,6 +129,40 @@ pub enum AttachmentMetadataValue {
116129 Boolean ( bool ) ,
117130}
118131
132+ impl AttachmentMetadataValue {
133+ pub fn get_number ( & self ) -> Option < u64 > {
134+ match self {
135+ AttachmentMetadataValue :: Number ( number) => Some ( * number) ,
136+ _ => None ,
137+ }
138+ }
139+ }
140+ #[ derive( Debug , PartialEq , Eq , Serialize , Deserialize , uniffi:: Record ) ]
141+ pub struct AttachmentDimensions {
142+ pub width : u64 ,
143+ pub height : u64 ,
144+ }
145+
146+ #[ uniffi:: export]
147+ pub fn get_attachment_dimensions ( attachment : & SupportAttachment ) -> Option < AttachmentDimensions > {
148+ let metadata = & attachment. metadata ;
149+
150+ let width = metadata
151+ . get ( & AttachmentMetadataKey :: Width )
152+ . and_then ( |v| v. get_number ( ) ) ;
153+ let height = metadata
154+ . get ( & AttachmentMetadataKey :: Height )
155+ . and_then ( |v| v. get_number ( ) ) ;
156+
157+ if let Some ( width) = width
158+ && let Some ( height) = height
159+ {
160+ return Some ( AttachmentDimensions { width, height } ) ;
161+ }
162+
163+ None
164+ }
165+
119166#[ derive( Debug , PartialEq , Eq , Serialize , Deserialize , uniffi:: Record ) ]
120167pub struct SupportAgentIdentity {
121168 pub id : u64 ,
@@ -151,6 +198,7 @@ impl std::fmt::Display for ConversationId {
151198#[ cfg( test) ]
152199mod tests {
153200 use super :: * ;
201+ use rstest:: * ;
154202
155203 #[ test]
156204 fn test_support_conversation_deserialization ( ) {
@@ -167,4 +215,83 @@ mod tests {
167215 serde_json:: from_str ( json) . expect ( "Failed to deserialize support conversation list" ) ;
168216 assert_eq ! ( conversation_list. len( ) , 11 ) ;
169217 }
218+
219+ #[ test]
220+ fn test_support_conversation_with_attachments_deserialization ( ) {
221+ let json = include_str ! (
222+ "../../tests/wpcom/support_tickets/single-conversation-with-attachments.json"
223+ ) ;
224+ let conversation: SupportConversation =
225+ serde_json:: from_str ( json) . expect ( "Failed to deserialize support conversation" ) ;
226+ assert_eq ! ( conversation. messages. len( ) , 1 ) ;
227+ assert_eq ! ( conversation. messages[ 0 ] . attachments. len( ) , 2 ) ;
228+ assert_eq ! (
229+ conversation. messages[ 0 ] . attachments[ 0 ] . filename,
230+ "sample-image-1.jpg"
231+ ) ;
232+ assert_eq ! (
233+ conversation. messages[ 0 ] . attachments[ 0 ] . content_type,
234+ "image/jpeg"
235+ ) ;
236+ assert_eq ! ( conversation. messages[ 0 ] . attachments[ 0 ] . size, 123456 ) ;
237+ assert_eq ! (
238+ conversation. messages[ 0 ] . attachments[ 0 ] . url,
239+ "https://example.com/attachments/token/token1/?name=sample-image-1.jpg"
240+ ) ;
241+
242+ let dimensions =
243+ get_attachment_dimensions ( & conversation. messages [ 0 ] . attachments [ 0 ] ) . unwrap ( ) ;
244+
245+ assert_eq ! ( dimensions. width, 1000 ) ;
246+ assert_eq ! ( dimensions. height, 800 ) ;
247+
248+ assert_eq ! (
249+ conversation. messages[ 0 ] . attachments[ 1 ] . filename,
250+ "sample-image-2.jpg"
251+ ) ;
252+ assert_eq ! (
253+ conversation. messages[ 0 ] . attachments[ 1 ] . content_type,
254+ "image/jpeg"
255+ ) ;
256+ assert_eq ! ( conversation. messages[ 0 ] . attachments[ 1 ] . size, 654321 ) ;
257+ assert_eq ! (
258+ conversation. messages[ 0 ] . attachments[ 1 ] . url,
259+ "https://example.com/attachments/token/token2/?name=sample-image-2.jpg"
260+ ) ;
261+
262+ let dimensions =
263+ get_attachment_dimensions ( & conversation. messages [ 0 ] . attachments [ 1 ] ) . unwrap ( ) ;
264+ assert_eq ! ( dimensions. width, 2000 ) ;
265+ assert_eq ! ( dimensions. height, 1600 ) ;
266+ }
267+
268+ #[ test]
269+ fn test_attachment_metadata_key_custom_deserialization ( ) {
270+ let json = r#"{"Custom": "test"}"# ;
271+ let metadata: HashMap < AttachmentMetadataKey , AttachmentMetadataValue > =
272+ serde_json:: from_str ( json) . expect ( "Failed to deserialize attachment metadata" ) ;
273+ assert_eq ! ( metadata. len( ) , 1 ) ;
274+ }
275+
276+ #[ rstest]
277+ #[ case( AttachmentMetadataKey :: Width , "Width" ) ]
278+ #[ case( AttachmentMetadataKey :: Height , "Height" ) ]
279+ #[ case(
280+ AttachmentMetadataKey :: Custom ( String :: from( "testlowercase" ) ) ,
281+ "testlowercase"
282+ ) ]
283+ #[ case(
284+ AttachmentMetadataKey :: Custom ( String :: from( "testWithCamelCase" ) ) ,
285+ "testWithCamelCase"
286+ ) ]
287+ #[ case(
288+ AttachmentMetadataKey :: Custom ( String :: from( "test_with_snake_case" ) ) ,
289+ "test_with_snake_case"
290+ ) ]
291+ fn test_attachment_metadata_key_to_string (
292+ #[ case] key : AttachmentMetadataKey ,
293+ #[ case] expected_str : & str ,
294+ ) {
295+ assert_eq ! ( key. to_string( ) , expected_str) ;
296+ }
170297}
0 commit comments