Skip to main content

stripe_shared/
price.rs

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