Skip to main content

app_store_server_library/models/
upload_message_image.rs

1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4const MAXIMUM_ALT_TEXT_LENGTH: usize = 150;
5
6/// The definition of an image with its alternative text.
7///
8/// [UploadMessageImage](https://developer.apple.com/documentation/retentionmessaging/uploadmessageimage)
9#[derive(Debug, Clone, Deserialize, Serialize, Hash, PartialEq, Eq)]
10pub struct UploadMessageImage {
11    /// The unique identifier of an image.
12    ///
13    /// [imageIdentifier](https://developer.apple.com/documentation/retentionmessaging/imageidentifier)
14    #[serde(rename = "imageIdentifier")]
15    pub image_identifier: Uuid,
16
17    /// The alternative text you provide for the corresponding image.
18    ///
19    /// [altText](https://developer.apple.com/documentation/retentionmessaging/alttext)
20    #[serde(rename = "altText")]
21    pub alt_text: String,
22}
23
24impl UploadMessageImage {
25    /// Creates a new UploadMessageImage with validation.
26    ///
27    /// # Errors
28    ///
29    /// Returns `ValidationError::AltTextTooLong` if alt_text exceeds 150 characters.
30    pub fn new(image_identifier: Uuid, alt_text: String) -> Result<Self, ValidationError> {
31        if alt_text.chars().count() > MAXIMUM_ALT_TEXT_LENGTH {
32            return Err(ValidationError::AltTextTooLong);
33        }
34        Ok(Self {
35            image_identifier,
36            alt_text,
37        })
38    }
39}
40
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub enum ValidationError {
43    AltTextTooLong,
44}
45
46impl std::fmt::Display for ValidationError {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        match self {
49            ValidationError::AltTextTooLong => {
50                write!(
51                    f,
52                    "Alt text exceeds maximum length of {} characters",
53                    MAXIMUM_ALT_TEXT_LENGTH
54                )
55            }
56        }
57    }
58}
59
60impl std::error::Error for ValidationError {}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn test_alt_text_length_counts_characters_not_bytes() {
68        // "é" is 2 bytes: a byte-based check would reject this at half the real limit.
69        let alt_text = "é".repeat(MAXIMUM_ALT_TEXT_LENGTH);
70        assert_eq!(alt_text.len(), MAXIMUM_ALT_TEXT_LENGTH * 2);
71        assert!(UploadMessageImage::new(Uuid::new_v4(), alt_text).is_ok());
72    }
73
74    #[test]
75    fn test_alt_text_too_long() {
76        let alt_text = "é".repeat(MAXIMUM_ALT_TEXT_LENGTH + 1);
77        assert_eq!(
78            UploadMessageImage::new(Uuid::new_v4(), alt_text),
79            Err(ValidationError::AltTextTooLong)
80        );
81    }
82}