Skip to main content

stripe_shared/
subscription_item.rs

1/// Subscription items allow you to create customer subscriptions with more than
2/// one plan, making it easy to represent complex billing relationships.
3///
4/// For more details see <<https://stripe.com/docs/api/subscription_items/object>>.
5#[derive(Clone)]
6#[cfg_attr(not(feature = "redact-generated-debug"), derive(Debug))]
7#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
8pub struct SubscriptionItem {
9    /// Define thresholds at which an invoice will be sent, and the related subscription advanced to a new billing period.
10    pub billing_thresholds: Option<stripe_shared::SubscriptionItemBillingThresholds>,
11    /// Time at which the object was created. Measured in seconds since the Unix epoch.
12    pub created: i64,
13    /// The end time of this subscription item's current billing period.
14    pub current_period_end: stripe_types::Timestamp,
15    /// The start time of this subscription item's current billing period.
16    pub current_period_start: stripe_types::Timestamp,
17    /// The discounts applied to the subscription item.
18    /// Subscription item discounts are applied before subscription discounts.
19    /// Use `expand[]=discounts` to expand each discount.
20    pub discounts: Vec<stripe_types::Expandable<stripe_shared::Discount>>,
21    /// Unique identifier for the object.
22    pub id: stripe_shared::SubscriptionItemId,
23    /// Set of [key-value pairs](https://docs.stripe.com/api/metadata) that you can attach to an object.
24    /// This can be useful for storing additional information about the object in a structured format.
25    pub metadata: std::collections::HashMap<String, String>,
26    pub plan: stripe_shared::Plan,
27    pub price: stripe_shared::Price,
28    /// The [quantity](https://docs.stripe.com/subscriptions/quantities) of the plan to which the customer should be subscribed.
29    pub quantity: Option<u64>,
30    /// The `subscription` this `subscription_item` belongs to.
31    pub subscription: String,
32    /// The tax rates which apply to this `subscription_item`.
33    /// When set, the `default_tax_rates` on the subscription do not apply to this `subscription_item`.
34    pub tax_rates: Option<Vec<stripe_shared::TaxRate>>,
35}
36#[cfg(feature = "redact-generated-debug")]
37impl std::fmt::Debug for SubscriptionItem {
38    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
39        f.debug_struct("SubscriptionItem").finish_non_exhaustive()
40    }
41}
42#[doc(hidden)]
43pub struct SubscriptionItemBuilder {
44    billing_thresholds: Option<Option<stripe_shared::SubscriptionItemBillingThresholds>>,
45    created: Option<i64>,
46    current_period_end: Option<stripe_types::Timestamp>,
47    current_period_start: Option<stripe_types::Timestamp>,
48    discounts: Option<Vec<stripe_types::Expandable<stripe_shared::Discount>>>,
49    id: Option<stripe_shared::SubscriptionItemId>,
50    metadata: Option<std::collections::HashMap<String, String>>,
51    plan: Option<stripe_shared::Plan>,
52    price: Option<stripe_shared::Price>,
53    quantity: Option<Option<u64>>,
54    subscription: Option<String>,
55    tax_rates: Option<Option<Vec<stripe_shared::TaxRate>>>,
56}
57
58#[allow(
59    unused_variables,
60    irrefutable_let_patterns,
61    clippy::let_unit_value,
62    clippy::match_single_binding,
63    clippy::single_match
64)]
65const _: () = {
66    use miniserde::de::{Map, Visitor};
67    use miniserde::json::Value;
68    use miniserde::{Deserialize, Result, make_place};
69    use stripe_types::miniserde_helpers::FromValueOpt;
70    use stripe_types::{MapBuilder, ObjectDeser};
71
72    make_place!(Place);
73
74    impl Deserialize for SubscriptionItem {
75        fn begin(out: &mut Option<Self>) -> &mut dyn Visitor {
76            Place::new(out)
77        }
78    }
79
80    struct Builder<'a> {
81        out: &'a mut Option<SubscriptionItem>,
82        builder: SubscriptionItemBuilder,
83    }
84
85    impl Visitor for Place<SubscriptionItem> {
86        fn map(&mut self) -> Result<Box<dyn Map + '_>> {
87            Ok(Box::new(Builder {
88                out: &mut self.out,
89                builder: SubscriptionItemBuilder::deser_default(),
90            }))
91        }
92    }
93
94    impl MapBuilder for SubscriptionItemBuilder {
95        type Out = SubscriptionItem;
96        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
97            Ok(match k {
98                "billing_thresholds" => Deserialize::begin(&mut self.billing_thresholds),
99                "created" => Deserialize::begin(&mut self.created),
100                "current_period_end" => Deserialize::begin(&mut self.current_period_end),
101                "current_period_start" => Deserialize::begin(&mut self.current_period_start),
102                "discounts" => Deserialize::begin(&mut self.discounts),
103                "id" => Deserialize::begin(&mut self.id),
104                "metadata" => Deserialize::begin(&mut self.metadata),
105                "plan" => Deserialize::begin(&mut self.plan),
106                "price" => Deserialize::begin(&mut self.price),
107                "quantity" => Deserialize::begin(&mut self.quantity),
108                "subscription" => Deserialize::begin(&mut self.subscription),
109                "tax_rates" => Deserialize::begin(&mut self.tax_rates),
110                _ => <dyn Visitor>::ignore(),
111            })
112        }
113
114        fn deser_default() -> Self {
115            Self {
116                billing_thresholds: Some(None),
117                created: None,
118                current_period_end: None,
119                current_period_start: None,
120                discounts: None,
121                id: None,
122                metadata: None,
123                plan: None,
124                price: None,
125                quantity: Some(None),
126                subscription: None,
127                tax_rates: Some(None),
128            }
129        }
130
131        fn take_out(&mut self) -> Option<Self::Out> {
132            let (
133                Some(billing_thresholds),
134                Some(created),
135                Some(current_period_end),
136                Some(current_period_start),
137                Some(discounts),
138                Some(id),
139                Some(metadata),
140                Some(plan),
141                Some(price),
142                Some(quantity),
143                Some(subscription),
144                Some(tax_rates),
145            ) = (
146                self.billing_thresholds,
147                self.created,
148                self.current_period_end,
149                self.current_period_start,
150                self.discounts.take(),
151                self.id.take(),
152                self.metadata.take(),
153                self.plan.take(),
154                self.price.take(),
155                self.quantity,
156                self.subscription.take(),
157                self.tax_rates.take(),
158            )
159            else {
160                return None;
161            };
162            Some(Self::Out {
163                billing_thresholds,
164                created,
165                current_period_end,
166                current_period_start,
167                discounts,
168                id,
169                metadata,
170                plan,
171                price,
172                quantity,
173                subscription,
174                tax_rates,
175            })
176        }
177    }
178
179    impl Map for Builder<'_> {
180        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
181            self.builder.key(k)
182        }
183
184        fn finish(&mut self) -> Result<()> {
185            *self.out = self.builder.take_out();
186            Ok(())
187        }
188    }
189
190    impl ObjectDeser for SubscriptionItem {
191        type Builder = SubscriptionItemBuilder;
192    }
193
194    impl FromValueOpt for SubscriptionItem {
195        fn from_value(v: Value) -> Option<Self> {
196            let Value::Object(obj) = v else {
197                return None;
198            };
199            let mut b = SubscriptionItemBuilder::deser_default();
200            for (k, v) in obj {
201                match k.as_str() {
202                    "billing_thresholds" => b.billing_thresholds = FromValueOpt::from_value(v),
203                    "created" => b.created = FromValueOpt::from_value(v),
204                    "current_period_end" => b.current_period_end = FromValueOpt::from_value(v),
205                    "current_period_start" => b.current_period_start = FromValueOpt::from_value(v),
206                    "discounts" => b.discounts = FromValueOpt::from_value(v),
207                    "id" => b.id = FromValueOpt::from_value(v),
208                    "metadata" => b.metadata = FromValueOpt::from_value(v),
209                    "plan" => b.plan = FromValueOpt::from_value(v),
210                    "price" => b.price = FromValueOpt::from_value(v),
211                    "quantity" => b.quantity = FromValueOpt::from_value(v),
212                    "subscription" => b.subscription = FromValueOpt::from_value(v),
213                    "tax_rates" => b.tax_rates = FromValueOpt::from_value(v),
214                    _ => {}
215                }
216            }
217            b.take_out()
218        }
219    }
220};
221#[cfg(feature = "serialize")]
222impl serde::Serialize for SubscriptionItem {
223    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
224        use serde::ser::SerializeStruct;
225        let mut s = s.serialize_struct("SubscriptionItem", 13)?;
226        s.serialize_field("billing_thresholds", &self.billing_thresholds)?;
227        s.serialize_field("created", &self.created)?;
228        s.serialize_field("current_period_end", &self.current_period_end)?;
229        s.serialize_field("current_period_start", &self.current_period_start)?;
230        s.serialize_field("discounts", &self.discounts)?;
231        s.serialize_field("id", &self.id)?;
232        s.serialize_field("metadata", &self.metadata)?;
233        s.serialize_field("plan", &self.plan)?;
234        s.serialize_field("price", &self.price)?;
235        s.serialize_field("quantity", &self.quantity)?;
236        s.serialize_field("subscription", &self.subscription)?;
237        s.serialize_field("tax_rates", &self.tax_rates)?;
238
239        s.serialize_field("object", "subscription_item")?;
240        s.end()
241    }
242}
243impl stripe_types::Object for SubscriptionItem {
244    type Id = stripe_shared::SubscriptionItemId;
245    fn id(&self) -> &Self::Id {
246        &self.id
247    }
248
249    fn into_id(self) -> Self::Id {
250        self.id
251    }
252}
253stripe_types::def_id!(SubscriptionItemId);