Skip to main content

storekit/
subscription.rs

1use serde::Deserialize;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4/// Wraps `StoreKit.Product.SubscriptionPeriod.Unit`.
5pub enum SubscriptionPeriodUnit {
6    /// Represents the `Day` `StoreKit` case.
7    Day,
8    /// Represents the `Week` `StoreKit` case.
9    Week,
10    /// Represents the `Month` `StoreKit` case.
11    Month,
12    /// Represents the `Year` `StoreKit` case.
13    Year,
14    /// Preserves an unrecognized `StoreKit` case.
15    Unknown(String),
16}
17
18impl SubscriptionPeriodUnit {
19    /// Returns the raw `StoreKit` string for this subscription period unit.
20    pub fn as_str(&self) -> &str {
21        match self {
22            Self::Day => "day",
23            Self::Week => "week",
24            Self::Month => "month",
25            Self::Year => "year",
26            Self::Unknown(value) => value.as_str(),
27        }
28    }
29
30    pub(crate) fn from_raw(raw: String) -> Self {
31        match raw.as_str() {
32            "day" => Self::Day,
33            "week" => Self::Week,
34            "month" => Self::Month,
35            "year" => Self::Year,
36            _ => Self::Unknown(raw),
37        }
38    }
39}
40
41#[derive(Debug, Clone, PartialEq, Eq)]
42/// Wraps `StoreKit.Product.SubscriptionPeriod`.
43pub struct SubscriptionPeriod {
44    /// Subscription period unit reported by `StoreKit`.
45    pub unit: SubscriptionPeriodUnit,
46    /// Value returned by `StoreKit`.
47    pub value: i64,
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
51/// Wraps `StoreKit.Product.SubscriptionOffer.OfferType`.
52pub enum SubscriptionOfferType {
53    /// Represents the `Introductory` `StoreKit` case.
54    Introductory,
55    /// Represents the `Promotional` `StoreKit` case.
56    Promotional,
57    /// Represents the `WinBack` `StoreKit` case.
58    WinBack,
59    /// Preserves an unrecognized `StoreKit` case.
60    Unknown(String),
61}
62
63impl SubscriptionOfferType {
64    /// Returns the raw `StoreKit` string for this subscription offer type.
65    pub fn as_str(&self) -> &str {
66        match self {
67            Self::Introductory => "introductory",
68            Self::Promotional => "promotional",
69            Self::WinBack => "winBack",
70            Self::Unknown(value) => value.as_str(),
71        }
72    }
73
74    pub(crate) fn from_raw(raw: String) -> Self {
75        match raw.as_str() {
76            "introductory" => Self::Introductory,
77            "promotional" => Self::Promotional,
78            "winBack" => Self::WinBack,
79            _ => Self::Unknown(raw),
80        }
81    }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
85/// Wraps `StoreKit.Product.SubscriptionOffer.PaymentMode`.
86pub enum SubscriptionPaymentMode {
87    /// Represents the `PayAsYouGo` `StoreKit` case.
88    PayAsYouGo,
89    /// Represents the `PayUpFront` `StoreKit` case.
90    PayUpFront,
91    /// Represents the `FreeTrial` `StoreKit` case.
92    FreeTrial,
93    /// Preserves an unrecognized `StoreKit` case.
94    Unknown(String),
95}
96
97impl SubscriptionPaymentMode {
98    /// Returns the raw `StoreKit` string for this subscription payment mode.
99    pub fn as_str(&self) -> &str {
100        match self {
101            Self::PayAsYouGo => "payAsYouGo",
102            Self::PayUpFront => "payUpFront",
103            Self::FreeTrial => "freeTrial",
104            Self::Unknown(value) => value.as_str(),
105        }
106    }
107
108    pub(crate) fn from_raw(raw: String) -> Self {
109        match raw.as_str() {
110            "payAsYouGo" => Self::PayAsYouGo,
111            "payUpFront" => Self::PayUpFront,
112            "freeTrial" => Self::FreeTrial,
113            _ => Self::Unknown(raw),
114        }
115    }
116}
117
118#[derive(Debug, Clone, PartialEq, Eq)]
119/// Wraps `StoreKit.Product.SubscriptionOffer`.
120pub struct SubscriptionOffer {
121    /// `StoreKit` identifier for this value.
122    pub id: Option<String>,
123    /// Offer type reported by `StoreKit`.
124    pub offer_type: SubscriptionOfferType,
125    /// Price reported by `StoreKit`.
126    pub price: String,
127    /// Localized display price reported by `StoreKit`.
128    pub display_price: String,
129    /// Subscription period reported by `StoreKit`.
130    pub period: SubscriptionPeriod,
131    /// Number of periods reported by `StoreKit`.
132    pub period_count: i64,
133    /// Payment mode reported by `StoreKit`.
134    pub payment_mode: SubscriptionPaymentMode,
135}
136
137#[derive(Debug, Deserialize)]
138pub(crate) struct SubscriptionPeriodPayload {
139    unit: String,
140    value: i64,
141}
142
143impl SubscriptionPeriodPayload {
144    pub(crate) fn into_subscription_period(self) -> SubscriptionPeriod {
145        SubscriptionPeriod {
146            unit: SubscriptionPeriodUnit::from_raw(self.unit),
147            value: self.value,
148        }
149    }
150}
151
152#[derive(Debug, Deserialize)]
153pub(crate) struct SubscriptionOfferPayload {
154    id: Option<String>,
155    #[serde(rename = "type")]
156    offer_type: String,
157    price: String,
158    #[serde(rename = "displayPrice")]
159    display_price: String,
160    period: SubscriptionPeriodPayload,
161    #[serde(rename = "periodCount")]
162    period_count: i64,
163    #[serde(rename = "paymentMode")]
164    payment_mode: String,
165}
166
167impl SubscriptionOfferPayload {
168    pub(crate) fn into_subscription_offer(self) -> SubscriptionOffer {
169        SubscriptionOffer {
170            id: self.id,
171            offer_type: SubscriptionOfferType::from_raw(self.offer_type),
172            price: self.price,
173            display_price: self.display_price,
174            period: self.period.into_subscription_period(),
175            period_count: self.period_count,
176            payment_mode: SubscriptionPaymentMode::from_raw(self.payment_mode),
177        }
178    }
179}