stripe_shared/
plan.rs

1/// You can now model subscriptions more flexibly using the [Prices API](https://stripe.com/docs/api#prices).
2/// It replaces the Plans API and is backwards compatible to simplify your migration.
3///
4/// Plans define the base price, currency, and billing cycle for recurring purchases of products.
5/// [Products](https://stripe.com/docs/api#products) help you track inventory or provisioning, and plans help you track pricing.
6/// Different physical goods or levels of service should be represented by products, and pricing options should be represented by plans.
7/// This approach lets you change prices without having to change your provisioning scheme.
8///
9/// For example, you might have a single "gold" product that has plans for $10/month, $100/year, €9/month, and €90/year.
10///
11/// Related guides: [Set up a subscription](https://stripe.com/docs/billing/subscriptions/set-up-subscription) and more about [products and prices](https://stripe.com/docs/products-prices/overview).
12///
13/// For more details see <<https://stripe.com/docs/api/plans/object>>.
14#[derive(Clone, Debug)]
15#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
16pub struct Plan {
17    /// Whether the plan can be used for new purchases.
18    pub active: bool,
19    /// The unit amount in cents (or local equivalent) to be charged, represented as a whole integer if possible.
20    /// Only set if `billing_scheme=per_unit`.
21    pub amount: Option<i64>,
22    /// The unit amount in cents (or local equivalent) to be charged, represented as a decimal string with at most 12 decimal places.
23    /// Only set if `billing_scheme=per_unit`.
24    pub amount_decimal: Option<String>,
25    /// Describes how to compute the price per period.
26    /// Either `per_unit` or `tiered`.
27    /// `per_unit` indicates that the fixed amount (specified in `amount`) will be charged per unit in `quantity` (for plans with `usage_type=licensed`), or per unit of total usage (for plans with `usage_type=metered`).
28    /// `tiered` indicates that the unit pricing will be computed using a tiering strategy as defined using the `tiers` and `tiers_mode` attributes.
29    pub billing_scheme: stripe_shared::PlanBillingScheme,
30    /// Time at which the object was created. Measured in seconds since the Unix epoch.
31    pub created: stripe_types::Timestamp,
32    /// Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase.
33    /// Must be a [supported currency](https://stripe.com/docs/currencies).
34    pub currency: stripe_types::Currency,
35    /// Unique identifier for the object.
36    pub id: stripe_shared::PlanId,
37    /// The frequency at which a subscription is billed. One of `day`, `week`, `month` or `year`.
38    pub interval: stripe_shared::PlanInterval,
39    /// The number of intervals (specified in the `interval` attribute) between subscription billings.
40    /// For example, `interval=month` and `interval_count=3` bills every 3 months.
41    pub interval_count: u64,
42    /// Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode.
43    pub livemode: bool,
44    /// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object.
45    /// This can be useful for storing additional information about the object in a structured format.
46    pub metadata: Option<std::collections::HashMap<String, String>>,
47    /// The meter tracking the usage of a metered price
48    pub meter: Option<String>,
49    /// A brief description of the plan, hidden from customers.
50    pub nickname: Option<String>,
51    /// The product whose pricing this plan determines.
52    pub product: Option<stripe_types::Expandable<stripe_shared::Product>>,
53    /// Each element represents a pricing tier.
54    /// This parameter requires `billing_scheme` to be set to `tiered`.
55    /// See also the documentation for `billing_scheme`.
56    pub tiers: Option<Vec<stripe_shared::PlanTier>>,
57    /// Defines if the tiering price should be `graduated` or `volume` based.
58    /// In `volume`-based tiering, the maximum quantity within a period determines the per unit price.
59    /// In `graduated` tiering, pricing can change as the quantity grows.
60    pub tiers_mode: Option<stripe_shared::PlanTiersMode>,
61    /// Apply a transformation to the reported usage or set quantity before computing the amount billed.
62    /// Cannot be combined with `tiers`.
63    pub transform_usage: Option<stripe_shared::TransformUsage>,
64    /// Default number of trial days when subscribing a customer to this plan using [`trial_from_plan=true`](https://stripe.com/docs/api#create_subscription-trial_from_plan).
65    pub trial_period_days: Option<u32>,
66    /// Configures how the quantity per period should be determined.
67    /// Can be either `metered` or `licensed`.
68    /// `licensed` automatically bills the `quantity` set when adding it to a subscription.
69    /// `metered` aggregates the total usage based on usage records.
70    /// Defaults to `licensed`.
71    pub usage_type: stripe_shared::PlanUsageType,
72}
73#[doc(hidden)]
74pub struct PlanBuilder {
75    active: Option<bool>,
76    amount: Option<Option<i64>>,
77    amount_decimal: Option<Option<String>>,
78    billing_scheme: Option<stripe_shared::PlanBillingScheme>,
79    created: Option<stripe_types::Timestamp>,
80    currency: Option<stripe_types::Currency>,
81    id: Option<stripe_shared::PlanId>,
82    interval: Option<stripe_shared::PlanInterval>,
83    interval_count: Option<u64>,
84    livemode: Option<bool>,
85    metadata: Option<Option<std::collections::HashMap<String, String>>>,
86    meter: Option<Option<String>>,
87    nickname: Option<Option<String>>,
88    product: Option<Option<stripe_types::Expandable<stripe_shared::Product>>>,
89    tiers: Option<Option<Vec<stripe_shared::PlanTier>>>,
90    tiers_mode: Option<Option<stripe_shared::PlanTiersMode>>,
91    transform_usage: Option<Option<stripe_shared::TransformUsage>>,
92    trial_period_days: Option<Option<u32>>,
93    usage_type: Option<stripe_shared::PlanUsageType>,
94}
95
96#[allow(
97    unused_variables,
98    irrefutable_let_patterns,
99    clippy::let_unit_value,
100    clippy::match_single_binding,
101    clippy::single_match
102)]
103const _: () = {
104    use miniserde::de::{Map, Visitor};
105    use miniserde::json::Value;
106    use miniserde::{Deserialize, Result, make_place};
107    use stripe_types::miniserde_helpers::FromValueOpt;
108    use stripe_types::{MapBuilder, ObjectDeser};
109
110    make_place!(Place);
111
112    impl Deserialize for Plan {
113        fn begin(out: &mut Option<Self>) -> &mut dyn Visitor {
114            Place::new(out)
115        }
116    }
117
118    struct Builder<'a> {
119        out: &'a mut Option<Plan>,
120        builder: PlanBuilder,
121    }
122
123    impl Visitor for Place<Plan> {
124        fn map(&mut self) -> Result<Box<dyn Map + '_>> {
125            Ok(Box::new(Builder { out: &mut self.out, builder: PlanBuilder::deser_default() }))
126        }
127    }
128
129    impl MapBuilder for PlanBuilder {
130        type Out = Plan;
131        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
132            Ok(match k {
133                "active" => Deserialize::begin(&mut self.active),
134                "amount" => Deserialize::begin(&mut self.amount),
135                "amount_decimal" => Deserialize::begin(&mut self.amount_decimal),
136                "billing_scheme" => Deserialize::begin(&mut self.billing_scheme),
137                "created" => Deserialize::begin(&mut self.created),
138                "currency" => Deserialize::begin(&mut self.currency),
139                "id" => Deserialize::begin(&mut self.id),
140                "interval" => Deserialize::begin(&mut self.interval),
141                "interval_count" => Deserialize::begin(&mut self.interval_count),
142                "livemode" => Deserialize::begin(&mut self.livemode),
143                "metadata" => Deserialize::begin(&mut self.metadata),
144                "meter" => Deserialize::begin(&mut self.meter),
145                "nickname" => Deserialize::begin(&mut self.nickname),
146                "product" => Deserialize::begin(&mut self.product),
147                "tiers" => Deserialize::begin(&mut self.tiers),
148                "tiers_mode" => Deserialize::begin(&mut self.tiers_mode),
149                "transform_usage" => Deserialize::begin(&mut self.transform_usage),
150                "trial_period_days" => Deserialize::begin(&mut self.trial_period_days),
151                "usage_type" => Deserialize::begin(&mut self.usage_type),
152                _ => <dyn Visitor>::ignore(),
153            })
154        }
155
156        fn deser_default() -> Self {
157            Self {
158                active: Deserialize::default(),
159                amount: Deserialize::default(),
160                amount_decimal: Deserialize::default(),
161                billing_scheme: Deserialize::default(),
162                created: Deserialize::default(),
163                currency: Deserialize::default(),
164                id: Deserialize::default(),
165                interval: Deserialize::default(),
166                interval_count: Deserialize::default(),
167                livemode: Deserialize::default(),
168                metadata: Deserialize::default(),
169                meter: Deserialize::default(),
170                nickname: Deserialize::default(),
171                product: Deserialize::default(),
172                tiers: Deserialize::default(),
173                tiers_mode: Deserialize::default(),
174                transform_usage: Deserialize::default(),
175                trial_period_days: Deserialize::default(),
176                usage_type: Deserialize::default(),
177            }
178        }
179
180        fn take_out(&mut self) -> Option<Self::Out> {
181            let (
182                Some(active),
183                Some(amount),
184                Some(amount_decimal),
185                Some(billing_scheme),
186                Some(created),
187                Some(currency),
188                Some(id),
189                Some(interval),
190                Some(interval_count),
191                Some(livemode),
192                Some(metadata),
193                Some(meter),
194                Some(nickname),
195                Some(product),
196                Some(tiers),
197                Some(tiers_mode),
198                Some(transform_usage),
199                Some(trial_period_days),
200                Some(usage_type),
201            ) = (
202                self.active,
203                self.amount,
204                self.amount_decimal.take(),
205                self.billing_scheme.take(),
206                self.created,
207                self.currency.take(),
208                self.id.take(),
209                self.interval.take(),
210                self.interval_count,
211                self.livemode,
212                self.metadata.take(),
213                self.meter.take(),
214                self.nickname.take(),
215                self.product.take(),
216                self.tiers.take(),
217                self.tiers_mode.take(),
218                self.transform_usage.take(),
219                self.trial_period_days,
220                self.usage_type.take(),
221            )
222            else {
223                return None;
224            };
225            Some(Self::Out {
226                active,
227                amount,
228                amount_decimal,
229                billing_scheme,
230                created,
231                currency,
232                id,
233                interval,
234                interval_count,
235                livemode,
236                metadata,
237                meter,
238                nickname,
239                product,
240                tiers,
241                tiers_mode,
242                transform_usage,
243                trial_period_days,
244                usage_type,
245            })
246        }
247    }
248
249    impl Map for Builder<'_> {
250        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
251            self.builder.key(k)
252        }
253
254        fn finish(&mut self) -> Result<()> {
255            *self.out = self.builder.take_out();
256            Ok(())
257        }
258    }
259
260    impl ObjectDeser for Plan {
261        type Builder = PlanBuilder;
262    }
263
264    impl FromValueOpt for Plan {
265        fn from_value(v: Value) -> Option<Self> {
266            let Value::Object(obj) = v else {
267                return None;
268            };
269            let mut b = PlanBuilder::deser_default();
270            for (k, v) in obj {
271                match k.as_str() {
272                    "active" => b.active = FromValueOpt::from_value(v),
273                    "amount" => b.amount = FromValueOpt::from_value(v),
274                    "amount_decimal" => b.amount_decimal = FromValueOpt::from_value(v),
275                    "billing_scheme" => b.billing_scheme = FromValueOpt::from_value(v),
276                    "created" => b.created = FromValueOpt::from_value(v),
277                    "currency" => b.currency = FromValueOpt::from_value(v),
278                    "id" => b.id = FromValueOpt::from_value(v),
279                    "interval" => b.interval = FromValueOpt::from_value(v),
280                    "interval_count" => b.interval_count = FromValueOpt::from_value(v),
281                    "livemode" => b.livemode = FromValueOpt::from_value(v),
282                    "metadata" => b.metadata = FromValueOpt::from_value(v),
283                    "meter" => b.meter = FromValueOpt::from_value(v),
284                    "nickname" => b.nickname = FromValueOpt::from_value(v),
285                    "product" => b.product = FromValueOpt::from_value(v),
286                    "tiers" => b.tiers = FromValueOpt::from_value(v),
287                    "tiers_mode" => b.tiers_mode = FromValueOpt::from_value(v),
288                    "transform_usage" => b.transform_usage = FromValueOpt::from_value(v),
289                    "trial_period_days" => b.trial_period_days = FromValueOpt::from_value(v),
290                    "usage_type" => b.usage_type = FromValueOpt::from_value(v),
291                    _ => {}
292                }
293            }
294            b.take_out()
295        }
296    }
297};
298#[cfg(feature = "serialize")]
299impl serde::Serialize for Plan {
300    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
301        use serde::ser::SerializeStruct;
302        let mut s = s.serialize_struct("Plan", 20)?;
303        s.serialize_field("active", &self.active)?;
304        s.serialize_field("amount", &self.amount)?;
305        s.serialize_field("amount_decimal", &self.amount_decimal)?;
306        s.serialize_field("billing_scheme", &self.billing_scheme)?;
307        s.serialize_field("created", &self.created)?;
308        s.serialize_field("currency", &self.currency)?;
309        s.serialize_field("id", &self.id)?;
310        s.serialize_field("interval", &self.interval)?;
311        s.serialize_field("interval_count", &self.interval_count)?;
312        s.serialize_field("livemode", &self.livemode)?;
313        s.serialize_field("metadata", &self.metadata)?;
314        s.serialize_field("meter", &self.meter)?;
315        s.serialize_field("nickname", &self.nickname)?;
316        s.serialize_field("product", &self.product)?;
317        s.serialize_field("tiers", &self.tiers)?;
318        s.serialize_field("tiers_mode", &self.tiers_mode)?;
319        s.serialize_field("transform_usage", &self.transform_usage)?;
320        s.serialize_field("trial_period_days", &self.trial_period_days)?;
321        s.serialize_field("usage_type", &self.usage_type)?;
322
323        s.serialize_field("object", "plan")?;
324        s.end()
325    }
326}
327impl stripe_types::Object for Plan {
328    type Id = stripe_shared::PlanId;
329    fn id(&self) -> &Self::Id {
330        &self.id
331    }
332
333    fn into_id(self) -> Self::Id {
334        self.id
335    }
336}
337stripe_types::def_id!(PlanId);
338#[derive(Clone, Eq, PartialEq)]
339#[non_exhaustive]
340pub enum PlanBillingScheme {
341    PerUnit,
342    Tiered,
343    /// An unrecognized value from Stripe. Should not be used as a request parameter.
344    Unknown(String),
345}
346impl PlanBillingScheme {
347    pub fn as_str(&self) -> &str {
348        use PlanBillingScheme::*;
349        match self {
350            PerUnit => "per_unit",
351            Tiered => "tiered",
352            Unknown(v) => v,
353        }
354    }
355}
356
357impl std::str::FromStr for PlanBillingScheme {
358    type Err = std::convert::Infallible;
359    fn from_str(s: &str) -> Result<Self, Self::Err> {
360        use PlanBillingScheme::*;
361        match s {
362            "per_unit" => Ok(PerUnit),
363            "tiered" => Ok(Tiered),
364            v => {
365                tracing::warn!("Unknown value '{}' for enum '{}'", v, "PlanBillingScheme");
366                Ok(Unknown(v.to_owned()))
367            }
368        }
369    }
370}
371impl std::fmt::Display for PlanBillingScheme {
372    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
373        f.write_str(self.as_str())
374    }
375}
376
377impl std::fmt::Debug for PlanBillingScheme {
378    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
379        f.write_str(self.as_str())
380    }
381}
382impl serde::Serialize for PlanBillingScheme {
383    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
384    where
385        S: serde::Serializer,
386    {
387        serializer.serialize_str(self.as_str())
388    }
389}
390impl miniserde::Deserialize for PlanBillingScheme {
391    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
392        crate::Place::new(out)
393    }
394}
395
396impl miniserde::de::Visitor for crate::Place<PlanBillingScheme> {
397    fn string(&mut self, s: &str) -> miniserde::Result<()> {
398        use std::str::FromStr;
399        self.out = Some(PlanBillingScheme::from_str(s).expect("infallible"));
400        Ok(())
401    }
402}
403
404stripe_types::impl_from_val_with_from_str!(PlanBillingScheme);
405#[cfg(feature = "deserialize")]
406impl<'de> serde::Deserialize<'de> for PlanBillingScheme {
407    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
408        use std::str::FromStr;
409        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
410        Ok(Self::from_str(&s).expect("infallible"))
411    }
412}
413#[derive(Clone, Eq, PartialEq)]
414#[non_exhaustive]
415pub enum PlanInterval {
416    Day,
417    Month,
418    Week,
419    Year,
420    /// An unrecognized value from Stripe. Should not be used as a request parameter.
421    Unknown(String),
422}
423impl PlanInterval {
424    pub fn as_str(&self) -> &str {
425        use PlanInterval::*;
426        match self {
427            Day => "day",
428            Month => "month",
429            Week => "week",
430            Year => "year",
431            Unknown(v) => v,
432        }
433    }
434}
435
436impl std::str::FromStr for PlanInterval {
437    type Err = std::convert::Infallible;
438    fn from_str(s: &str) -> Result<Self, Self::Err> {
439        use PlanInterval::*;
440        match s {
441            "day" => Ok(Day),
442            "month" => Ok(Month),
443            "week" => Ok(Week),
444            "year" => Ok(Year),
445            v => {
446                tracing::warn!("Unknown value '{}' for enum '{}'", v, "PlanInterval");
447                Ok(Unknown(v.to_owned()))
448            }
449        }
450    }
451}
452impl std::fmt::Display for PlanInterval {
453    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
454        f.write_str(self.as_str())
455    }
456}
457
458impl std::fmt::Debug for PlanInterval {
459    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
460        f.write_str(self.as_str())
461    }
462}
463impl serde::Serialize for PlanInterval {
464    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
465    where
466        S: serde::Serializer,
467    {
468        serializer.serialize_str(self.as_str())
469    }
470}
471impl miniserde::Deserialize for PlanInterval {
472    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
473        crate::Place::new(out)
474    }
475}
476
477impl miniserde::de::Visitor for crate::Place<PlanInterval> {
478    fn string(&mut self, s: &str) -> miniserde::Result<()> {
479        use std::str::FromStr;
480        self.out = Some(PlanInterval::from_str(s).expect("infallible"));
481        Ok(())
482    }
483}
484
485stripe_types::impl_from_val_with_from_str!(PlanInterval);
486#[cfg(feature = "deserialize")]
487impl<'de> serde::Deserialize<'de> for PlanInterval {
488    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
489        use std::str::FromStr;
490        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
491        Ok(Self::from_str(&s).expect("infallible"))
492    }
493}
494#[derive(Clone, Eq, PartialEq)]
495#[non_exhaustive]
496pub enum PlanTiersMode {
497    Graduated,
498    Volume,
499    /// An unrecognized value from Stripe. Should not be used as a request parameter.
500    Unknown(String),
501}
502impl PlanTiersMode {
503    pub fn as_str(&self) -> &str {
504        use PlanTiersMode::*;
505        match self {
506            Graduated => "graduated",
507            Volume => "volume",
508            Unknown(v) => v,
509        }
510    }
511}
512
513impl std::str::FromStr for PlanTiersMode {
514    type Err = std::convert::Infallible;
515    fn from_str(s: &str) -> Result<Self, Self::Err> {
516        use PlanTiersMode::*;
517        match s {
518            "graduated" => Ok(Graduated),
519            "volume" => Ok(Volume),
520            v => {
521                tracing::warn!("Unknown value '{}' for enum '{}'", v, "PlanTiersMode");
522                Ok(Unknown(v.to_owned()))
523            }
524        }
525    }
526}
527impl std::fmt::Display for PlanTiersMode {
528    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
529        f.write_str(self.as_str())
530    }
531}
532
533impl std::fmt::Debug for PlanTiersMode {
534    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
535        f.write_str(self.as_str())
536    }
537}
538impl serde::Serialize for PlanTiersMode {
539    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
540    where
541        S: serde::Serializer,
542    {
543        serializer.serialize_str(self.as_str())
544    }
545}
546impl miniserde::Deserialize for PlanTiersMode {
547    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
548        crate::Place::new(out)
549    }
550}
551
552impl miniserde::de::Visitor for crate::Place<PlanTiersMode> {
553    fn string(&mut self, s: &str) -> miniserde::Result<()> {
554        use std::str::FromStr;
555        self.out = Some(PlanTiersMode::from_str(s).expect("infallible"));
556        Ok(())
557    }
558}
559
560stripe_types::impl_from_val_with_from_str!(PlanTiersMode);
561#[cfg(feature = "deserialize")]
562impl<'de> serde::Deserialize<'de> for PlanTiersMode {
563    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
564        use std::str::FromStr;
565        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
566        Ok(Self::from_str(&s).expect("infallible"))
567    }
568}
569#[derive(Clone, Eq, PartialEq)]
570#[non_exhaustive]
571pub enum PlanUsageType {
572    Licensed,
573    Metered,
574    /// An unrecognized value from Stripe. Should not be used as a request parameter.
575    Unknown(String),
576}
577impl PlanUsageType {
578    pub fn as_str(&self) -> &str {
579        use PlanUsageType::*;
580        match self {
581            Licensed => "licensed",
582            Metered => "metered",
583            Unknown(v) => v,
584        }
585    }
586}
587
588impl std::str::FromStr for PlanUsageType {
589    type Err = std::convert::Infallible;
590    fn from_str(s: &str) -> Result<Self, Self::Err> {
591        use PlanUsageType::*;
592        match s {
593            "licensed" => Ok(Licensed),
594            "metered" => Ok(Metered),
595            v => {
596                tracing::warn!("Unknown value '{}' for enum '{}'", v, "PlanUsageType");
597                Ok(Unknown(v.to_owned()))
598            }
599        }
600    }
601}
602impl std::fmt::Display for PlanUsageType {
603    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
604        f.write_str(self.as_str())
605    }
606}
607
608impl std::fmt::Debug for PlanUsageType {
609    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
610        f.write_str(self.as_str())
611    }
612}
613impl serde::Serialize for PlanUsageType {
614    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
615    where
616        S: serde::Serializer,
617    {
618        serializer.serialize_str(self.as_str())
619    }
620}
621impl miniserde::Deserialize for PlanUsageType {
622    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
623        crate::Place::new(out)
624    }
625}
626
627impl miniserde::de::Visitor for crate::Place<PlanUsageType> {
628    fn string(&mut self, s: &str) -> miniserde::Result<()> {
629        use std::str::FromStr;
630        self.out = Some(PlanUsageType::from_str(s).expect("infallible"));
631        Ok(())
632    }
633}
634
635stripe_types::impl_from_val_with_from_str!(PlanUsageType);
636#[cfg(feature = "deserialize")]
637impl<'de> serde::Deserialize<'de> for PlanUsageType {
638    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
639        use std::str::FromStr;
640        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
641        Ok(Self::from_str(&s).expect("infallible"))
642    }
643}