Skip to main content

stripe_shared/
subscription_schedule.rs

1/// A subscription schedule allows you to create and manage the lifecycle of a subscription by predefining expected changes.
2///
3/// Related guide: [Subscription schedules](https://docs.stripe.com/billing/subscriptions/subscription-schedules).
4///
5/// For more details see <<https://stripe.com/docs/api/subscription_schedules/object>>.
6#[derive(Clone)]
7#[cfg_attr(not(feature = "redact-generated-debug"), derive(Debug))]
8#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
9pub struct SubscriptionSchedule {
10    /// ID of the Connect Application that created the schedule.
11    pub application: Option<stripe_types::Expandable<stripe_shared::Application>>,
12    pub billing_mode: stripe_shared::SubscriptionsResourceBillingMode,
13    /// Time at which the subscription schedule was canceled. Measured in seconds since the Unix epoch.
14    pub canceled_at: Option<stripe_types::Timestamp>,
15    /// Time at which the subscription schedule was completed. Measured in seconds since the Unix epoch.
16    pub completed_at: Option<stripe_types::Timestamp>,
17    /// Time at which the object was created. Measured in seconds since the Unix epoch.
18    pub created: stripe_types::Timestamp,
19    /// Object representing the start and end dates for the current phase of the subscription schedule, if it is `active`.
20    pub current_phase: Option<stripe_shared::SubscriptionScheduleCurrentPhase>,
21    /// ID of the customer who owns the subscription schedule.
22    pub customer: stripe_types::Expandable<stripe_shared::Customer>,
23    /// ID of the account who owns the subscription schedule.
24    pub customer_account: Option<String>,
25    pub default_settings: stripe_shared::SubscriptionSchedulesResourceDefaultSettings,
26    /// Behavior of the subscription schedule and underlying subscription when it ends.
27    /// Possible values are `release` or `cancel` with the default being `release`.
28    /// `release` will end the subscription schedule and keep the underlying subscription running.
29    /// `cancel` will end the subscription schedule and cancel the underlying subscription.
30    pub end_behavior: stripe_shared::SubscriptionScheduleEndBehavior,
31    /// Unique identifier for the object.
32    pub id: stripe_shared::SubscriptionScheduleId,
33    /// If the object exists in live mode, the value is `true`.
34    /// If the object exists in test mode, the value is `false`.
35    pub livemode: bool,
36    /// Set of [key-value pairs](https://docs.stripe.com/api/metadata) that you can attach to an object.
37    /// This can be useful for storing additional information about the object in a structured format.
38    pub metadata: Option<std::collections::HashMap<String, String>>,
39    /// Configuration for the subscription schedule's phases.
40    pub phases: Vec<stripe_shared::SubscriptionSchedulePhaseConfiguration>,
41    /// Time at which the subscription schedule was released. Measured in seconds since the Unix epoch.
42    pub released_at: Option<stripe_types::Timestamp>,
43    /// ID of the subscription once managed by the subscription schedule (if it is released).
44    pub released_subscription: Option<String>,
45    /// The present status of the subscription schedule.
46    /// Possible values are `not_started`, `active`, `completed`, `released`, and `canceled`.
47    /// You can read more about the different states in our [behavior guide](https://docs.stripe.com/billing/subscriptions/subscription-schedules).
48    pub status: SubscriptionScheduleStatus,
49    /// ID of the subscription managed by the subscription schedule.
50    pub subscription: Option<stripe_types::Expandable<stripe_shared::Subscription>>,
51    /// ID of the test clock this subscription schedule belongs to.
52    pub test_clock: Option<stripe_types::Expandable<stripe_shared::TestHelpersTestClock>>,
53}
54#[cfg(feature = "redact-generated-debug")]
55impl std::fmt::Debug for SubscriptionSchedule {
56    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
57        f.debug_struct("SubscriptionSchedule").finish_non_exhaustive()
58    }
59}
60#[doc(hidden)]
61pub struct SubscriptionScheduleBuilder {
62    application: Option<Option<stripe_types::Expandable<stripe_shared::Application>>>,
63    billing_mode: Option<stripe_shared::SubscriptionsResourceBillingMode>,
64    canceled_at: Option<Option<stripe_types::Timestamp>>,
65    completed_at: Option<Option<stripe_types::Timestamp>>,
66    created: Option<stripe_types::Timestamp>,
67    current_phase: Option<Option<stripe_shared::SubscriptionScheduleCurrentPhase>>,
68    customer: Option<stripe_types::Expandable<stripe_shared::Customer>>,
69    customer_account: Option<Option<String>>,
70    default_settings: Option<stripe_shared::SubscriptionSchedulesResourceDefaultSettings>,
71    end_behavior: Option<stripe_shared::SubscriptionScheduleEndBehavior>,
72    id: Option<stripe_shared::SubscriptionScheduleId>,
73    livemode: Option<bool>,
74    metadata: Option<Option<std::collections::HashMap<String, String>>>,
75    phases: Option<Vec<stripe_shared::SubscriptionSchedulePhaseConfiguration>>,
76    released_at: Option<Option<stripe_types::Timestamp>>,
77    released_subscription: Option<Option<String>>,
78    status: Option<SubscriptionScheduleStatus>,
79    subscription: Option<Option<stripe_types::Expandable<stripe_shared::Subscription>>>,
80    test_clock: Option<Option<stripe_types::Expandable<stripe_shared::TestHelpersTestClock>>>,
81}
82
83#[allow(
84    unused_variables,
85    irrefutable_let_patterns,
86    clippy::let_unit_value,
87    clippy::match_single_binding,
88    clippy::single_match
89)]
90const _: () = {
91    use miniserde::de::{Map, Visitor};
92    use miniserde::json::Value;
93    use miniserde::{Deserialize, Result, make_place};
94    use stripe_types::miniserde_helpers::FromValueOpt;
95    use stripe_types::{MapBuilder, ObjectDeser};
96
97    make_place!(Place);
98
99    impl Deserialize for SubscriptionSchedule {
100        fn begin(out: &mut Option<Self>) -> &mut dyn Visitor {
101            Place::new(out)
102        }
103    }
104
105    struct Builder<'a> {
106        out: &'a mut Option<SubscriptionSchedule>,
107        builder: SubscriptionScheduleBuilder,
108    }
109
110    impl Visitor for Place<SubscriptionSchedule> {
111        fn map(&mut self) -> Result<Box<dyn Map + '_>> {
112            Ok(Box::new(Builder {
113                out: &mut self.out,
114                builder: SubscriptionScheduleBuilder::deser_default(),
115            }))
116        }
117    }
118
119    impl MapBuilder for SubscriptionScheduleBuilder {
120        type Out = SubscriptionSchedule;
121        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
122            Ok(match k {
123                "application" => Deserialize::begin(&mut self.application),
124                "billing_mode" => Deserialize::begin(&mut self.billing_mode),
125                "canceled_at" => Deserialize::begin(&mut self.canceled_at),
126                "completed_at" => Deserialize::begin(&mut self.completed_at),
127                "created" => Deserialize::begin(&mut self.created),
128                "current_phase" => Deserialize::begin(&mut self.current_phase),
129                "customer" => Deserialize::begin(&mut self.customer),
130                "customer_account" => Deserialize::begin(&mut self.customer_account),
131                "default_settings" => Deserialize::begin(&mut self.default_settings),
132                "end_behavior" => Deserialize::begin(&mut self.end_behavior),
133                "id" => Deserialize::begin(&mut self.id),
134                "livemode" => Deserialize::begin(&mut self.livemode),
135                "metadata" => Deserialize::begin(&mut self.metadata),
136                "phases" => Deserialize::begin(&mut self.phases),
137                "released_at" => Deserialize::begin(&mut self.released_at),
138                "released_subscription" => Deserialize::begin(&mut self.released_subscription),
139                "status" => Deserialize::begin(&mut self.status),
140                "subscription" => Deserialize::begin(&mut self.subscription),
141                "test_clock" => Deserialize::begin(&mut self.test_clock),
142                _ => <dyn Visitor>::ignore(),
143            })
144        }
145
146        fn deser_default() -> Self {
147            Self {
148                application: Some(None),
149                billing_mode: None,
150                canceled_at: Some(None),
151                completed_at: Some(None),
152                created: None,
153                current_phase: Some(None),
154                customer: None,
155                customer_account: Some(None),
156                default_settings: None,
157                end_behavior: None,
158                id: None,
159                livemode: None,
160                metadata: Some(None),
161                phases: None,
162                released_at: Some(None),
163                released_subscription: Some(None),
164                status: None,
165                subscription: Some(None),
166                test_clock: Some(None),
167            }
168        }
169
170        fn take_out(&mut self) -> Option<Self::Out> {
171            let (
172                Some(application),
173                Some(billing_mode),
174                Some(canceled_at),
175                Some(completed_at),
176                Some(created),
177                Some(current_phase),
178                Some(customer),
179                Some(customer_account),
180                Some(default_settings),
181                Some(end_behavior),
182                Some(id),
183                Some(livemode),
184                Some(metadata),
185                Some(phases),
186                Some(released_at),
187                Some(released_subscription),
188                Some(status),
189                Some(subscription),
190                Some(test_clock),
191            ) = (
192                self.application.take(),
193                self.billing_mode.take(),
194                self.canceled_at,
195                self.completed_at,
196                self.created,
197                self.current_phase,
198                self.customer.take(),
199                self.customer_account.take(),
200                self.default_settings.take(),
201                self.end_behavior.take(),
202                self.id.take(),
203                self.livemode,
204                self.metadata.take(),
205                self.phases.take(),
206                self.released_at,
207                self.released_subscription.take(),
208                self.status.take(),
209                self.subscription.take(),
210                self.test_clock.take(),
211            )
212            else {
213                return None;
214            };
215            Some(Self::Out {
216                application,
217                billing_mode,
218                canceled_at,
219                completed_at,
220                created,
221                current_phase,
222                customer,
223                customer_account,
224                default_settings,
225                end_behavior,
226                id,
227                livemode,
228                metadata,
229                phases,
230                released_at,
231                released_subscription,
232                status,
233                subscription,
234                test_clock,
235            })
236        }
237    }
238
239    impl Map for Builder<'_> {
240        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
241            self.builder.key(k)
242        }
243
244        fn finish(&mut self) -> Result<()> {
245            *self.out = self.builder.take_out();
246            Ok(())
247        }
248    }
249
250    impl ObjectDeser for SubscriptionSchedule {
251        type Builder = SubscriptionScheduleBuilder;
252    }
253
254    impl FromValueOpt for SubscriptionSchedule {
255        fn from_value(v: Value) -> Option<Self> {
256            let Value::Object(obj) = v else {
257                return None;
258            };
259            let mut b = SubscriptionScheduleBuilder::deser_default();
260            for (k, v) in obj {
261                match k.as_str() {
262                    "application" => b.application = FromValueOpt::from_value(v),
263                    "billing_mode" => b.billing_mode = FromValueOpt::from_value(v),
264                    "canceled_at" => b.canceled_at = FromValueOpt::from_value(v),
265                    "completed_at" => b.completed_at = FromValueOpt::from_value(v),
266                    "created" => b.created = FromValueOpt::from_value(v),
267                    "current_phase" => b.current_phase = FromValueOpt::from_value(v),
268                    "customer" => b.customer = FromValueOpt::from_value(v),
269                    "customer_account" => b.customer_account = FromValueOpt::from_value(v),
270                    "default_settings" => b.default_settings = FromValueOpt::from_value(v),
271                    "end_behavior" => b.end_behavior = FromValueOpt::from_value(v),
272                    "id" => b.id = FromValueOpt::from_value(v),
273                    "livemode" => b.livemode = FromValueOpt::from_value(v),
274                    "metadata" => b.metadata = FromValueOpt::from_value(v),
275                    "phases" => b.phases = FromValueOpt::from_value(v),
276                    "released_at" => b.released_at = FromValueOpt::from_value(v),
277                    "released_subscription" => {
278                        b.released_subscription = FromValueOpt::from_value(v)
279                    }
280                    "status" => b.status = FromValueOpt::from_value(v),
281                    "subscription" => b.subscription = FromValueOpt::from_value(v),
282                    "test_clock" => b.test_clock = FromValueOpt::from_value(v),
283                    _ => {}
284                }
285            }
286            b.take_out()
287        }
288    }
289};
290#[cfg(feature = "serialize")]
291impl serde::Serialize for SubscriptionSchedule {
292    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
293        use serde::ser::SerializeStruct;
294        let mut s = s.serialize_struct("SubscriptionSchedule", 20)?;
295        s.serialize_field("application", &self.application)?;
296        s.serialize_field("billing_mode", &self.billing_mode)?;
297        s.serialize_field("canceled_at", &self.canceled_at)?;
298        s.serialize_field("completed_at", &self.completed_at)?;
299        s.serialize_field("created", &self.created)?;
300        s.serialize_field("current_phase", &self.current_phase)?;
301        s.serialize_field("customer", &self.customer)?;
302        s.serialize_field("customer_account", &self.customer_account)?;
303        s.serialize_field("default_settings", &self.default_settings)?;
304        s.serialize_field("end_behavior", &self.end_behavior)?;
305        s.serialize_field("id", &self.id)?;
306        s.serialize_field("livemode", &self.livemode)?;
307        s.serialize_field("metadata", &self.metadata)?;
308        s.serialize_field("phases", &self.phases)?;
309        s.serialize_field("released_at", &self.released_at)?;
310        s.serialize_field("released_subscription", &self.released_subscription)?;
311        s.serialize_field("status", &self.status)?;
312        s.serialize_field("subscription", &self.subscription)?;
313        s.serialize_field("test_clock", &self.test_clock)?;
314
315        s.serialize_field("object", "subscription_schedule")?;
316        s.end()
317    }
318}
319/// The present status of the subscription schedule.
320/// Possible values are `not_started`, `active`, `completed`, `released`, and `canceled`.
321/// You can read more about the different states in our [behavior guide](https://docs.stripe.com/billing/subscriptions/subscription-schedules).
322#[derive(Clone, Eq, PartialEq)]
323#[non_exhaustive]
324pub enum SubscriptionScheduleStatus {
325    Active,
326    Canceled,
327    Completed,
328    NotStarted,
329    Released,
330    /// An unrecognized value from Stripe. Should not be used as a request parameter.
331    Unknown(String),
332}
333impl SubscriptionScheduleStatus {
334    pub fn as_str(&self) -> &str {
335        use SubscriptionScheduleStatus::*;
336        match self {
337            Active => "active",
338            Canceled => "canceled",
339            Completed => "completed",
340            NotStarted => "not_started",
341            Released => "released",
342            Unknown(v) => v,
343        }
344    }
345}
346
347impl std::str::FromStr for SubscriptionScheduleStatus {
348    type Err = std::convert::Infallible;
349    fn from_str(s: &str) -> Result<Self, Self::Err> {
350        use SubscriptionScheduleStatus::*;
351        match s {
352            "active" => Ok(Active),
353            "canceled" => Ok(Canceled),
354            "completed" => Ok(Completed),
355            "not_started" => Ok(NotStarted),
356            "released" => Ok(Released),
357            v => {
358                tracing::warn!("Unknown value '{}' for enum '{}'", v, "SubscriptionScheduleStatus");
359                Ok(Unknown(v.to_owned()))
360            }
361        }
362    }
363}
364impl std::fmt::Display for SubscriptionScheduleStatus {
365    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
366        f.write_str(self.as_str())
367    }
368}
369
370#[cfg(not(feature = "redact-generated-debug"))]
371impl std::fmt::Debug for SubscriptionScheduleStatus {
372    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
373        f.write_str(self.as_str())
374    }
375}
376#[cfg(feature = "redact-generated-debug")]
377impl std::fmt::Debug for SubscriptionScheduleStatus {
378    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
379        f.debug_struct(stringify!(SubscriptionScheduleStatus)).finish_non_exhaustive()
380    }
381}
382#[cfg(feature = "serialize")]
383impl serde::Serialize for SubscriptionScheduleStatus {
384    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
385    where
386        S: serde::Serializer,
387    {
388        serializer.serialize_str(self.as_str())
389    }
390}
391impl miniserde::Deserialize for SubscriptionScheduleStatus {
392    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
393        crate::Place::new(out)
394    }
395}
396
397impl miniserde::de::Visitor for crate::Place<SubscriptionScheduleStatus> {
398    fn string(&mut self, s: &str) -> miniserde::Result<()> {
399        use std::str::FromStr;
400        self.out = Some(SubscriptionScheduleStatus::from_str(s).expect("infallible"));
401        Ok(())
402    }
403}
404
405stripe_types::impl_from_val_with_from_str!(SubscriptionScheduleStatus);
406#[cfg(feature = "deserialize")]
407impl<'de> serde::Deserialize<'de> for SubscriptionScheduleStatus {
408    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
409        use std::str::FromStr;
410        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
411        Ok(Self::from_str(&s).expect("infallible"))
412    }
413}
414impl stripe_types::Object for SubscriptionSchedule {
415    type Id = stripe_shared::SubscriptionScheduleId;
416    fn id(&self) -> &Self::Id {
417        &self.id
418    }
419
420    fn into_id(self) -> Self::Id {
421        self.id
422    }
423}
424stripe_types::def_id!(SubscriptionScheduleId);
425#[derive(Clone, Eq, PartialEq)]
426#[non_exhaustive]
427pub enum SubscriptionScheduleEndBehavior {
428    Cancel,
429    None,
430    Release,
431    Renew,
432    /// An unrecognized value from Stripe. Should not be used as a request parameter.
433    Unknown(String),
434}
435impl SubscriptionScheduleEndBehavior {
436    pub fn as_str(&self) -> &str {
437        use SubscriptionScheduleEndBehavior::*;
438        match self {
439            Cancel => "cancel",
440            None => "none",
441            Release => "release",
442            Renew => "renew",
443            Unknown(v) => v,
444        }
445    }
446}
447
448impl std::str::FromStr for SubscriptionScheduleEndBehavior {
449    type Err = std::convert::Infallible;
450    fn from_str(s: &str) -> Result<Self, Self::Err> {
451        use SubscriptionScheduleEndBehavior::*;
452        match s {
453            "cancel" => Ok(Cancel),
454            "none" => Ok(None),
455            "release" => Ok(Release),
456            "renew" => Ok(Renew),
457            v => {
458                tracing::warn!(
459                    "Unknown value '{}' for enum '{}'",
460                    v,
461                    "SubscriptionScheduleEndBehavior"
462                );
463                Ok(Unknown(v.to_owned()))
464            }
465        }
466    }
467}
468impl std::fmt::Display for SubscriptionScheduleEndBehavior {
469    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
470        f.write_str(self.as_str())
471    }
472}
473
474#[cfg(not(feature = "redact-generated-debug"))]
475impl std::fmt::Debug for SubscriptionScheduleEndBehavior {
476    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
477        f.write_str(self.as_str())
478    }
479}
480#[cfg(feature = "redact-generated-debug")]
481impl std::fmt::Debug for SubscriptionScheduleEndBehavior {
482    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
483        f.debug_struct(stringify!(SubscriptionScheduleEndBehavior)).finish_non_exhaustive()
484    }
485}
486impl serde::Serialize for SubscriptionScheduleEndBehavior {
487    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
488    where
489        S: serde::Serializer,
490    {
491        serializer.serialize_str(self.as_str())
492    }
493}
494impl miniserde::Deserialize for SubscriptionScheduleEndBehavior {
495    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
496        crate::Place::new(out)
497    }
498}
499
500impl miniserde::de::Visitor for crate::Place<SubscriptionScheduleEndBehavior> {
501    fn string(&mut self, s: &str) -> miniserde::Result<()> {
502        use std::str::FromStr;
503        self.out = Some(SubscriptionScheduleEndBehavior::from_str(s).expect("infallible"));
504        Ok(())
505    }
506}
507
508stripe_types::impl_from_val_with_from_str!(SubscriptionScheduleEndBehavior);
509#[cfg(feature = "deserialize")]
510impl<'de> serde::Deserialize<'de> for SubscriptionScheduleEndBehavior {
511    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
512        use std::str::FromStr;
513        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
514        Ok(Self::from_str(&s).expect("infallible"))
515    }
516}