stripe_shared/
invoice_line_item.rs

1/// Invoice Line Items represent the individual lines within an [invoice](https://stripe.com/docs/api/invoices) and only exist within the context of an invoice.
2///
3/// Each line item is backed by either an [invoice item](https://stripe.com/docs/api/invoiceitems) or a [subscription item](https://stripe.com/docs/api/subscription_items).
4#[derive(Clone, Debug)]
5#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
6pub struct InvoiceLineItem {
7    /// The amount, in cents (or local equivalent).
8    pub amount: i64,
9    /// Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase.
10    /// Must be a [supported currency](https://stripe.com/docs/currencies).
11    pub currency: stripe_types::Currency,
12    /// An arbitrary string attached to the object. Often useful for displaying to users.
13    pub description: Option<String>,
14    /// The amount of discount calculated per discount for this line item.
15    pub discount_amounts: Option<Vec<stripe_shared::DiscountsResourceDiscountAmount>>,
16    /// If true, discounts will apply to this line item. Always false for prorations.
17    pub discountable: bool,
18    /// The discounts applied to the invoice line item.
19    /// Line item discounts are applied before invoice discounts.
20    /// Use `expand[]=discounts` to expand each discount.
21    pub discounts: Vec<stripe_types::Expandable<stripe_shared::Discount>>,
22    /// Unique identifier for the object.
23    pub id: stripe_shared::InvoiceLineItemId,
24    /// The ID of the invoice that contains this line item.
25    pub invoice: Option<String>,
26    /// Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode.
27    pub livemode: bool,
28    /// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object.
29    /// This can be useful for storing additional information about the object in a structured format.
30    /// Note that for line items with `type=subscription`, `metadata` reflects the current metadata from the subscription associated with the line item, unless the invoice line was directly updated with different metadata after creation.
31    pub metadata: std::collections::HashMap<String, String>,
32    /// The parent that generated this line item.
33    pub parent:
34        Option<stripe_shared::BillingBillResourceInvoicingLinesParentsInvoiceLineItemParent>,
35    pub period: stripe_shared::InvoiceLineItemPeriod,
36    /// Contains pretax credit amounts (ex: discount, credit grants, etc) that apply to this line item.
37    pub pretax_credit_amounts: Option<Vec<stripe_shared::InvoicesResourcePretaxCreditAmount>>,
38    /// The pricing information of the line item.
39    pub pricing: Option<stripe_shared::BillingBillResourceInvoicingPricingPricing>,
40    /// The quantity of the subscription, if the line item is a subscription or a proration.
41    pub quantity: Option<u64>,
42    pub subscription: Option<stripe_types::Expandable<stripe_shared::Subscription>>,
43    /// The tax information of the line item.
44    pub taxes: Option<Vec<stripe_shared::BillingBillResourceInvoicingTaxesTax>>,
45}
46#[doc(hidden)]
47pub struct InvoiceLineItemBuilder {
48    amount: Option<i64>,
49    currency: Option<stripe_types::Currency>,
50    description: Option<Option<String>>,
51    discount_amounts: Option<Option<Vec<stripe_shared::DiscountsResourceDiscountAmount>>>,
52    discountable: Option<bool>,
53    discounts: Option<Vec<stripe_types::Expandable<stripe_shared::Discount>>>,
54    id: Option<stripe_shared::InvoiceLineItemId>,
55    invoice: Option<Option<String>>,
56    livemode: Option<bool>,
57    metadata: Option<std::collections::HashMap<String, String>>,
58    parent: Option<
59        Option<stripe_shared::BillingBillResourceInvoicingLinesParentsInvoiceLineItemParent>,
60    >,
61    period: Option<stripe_shared::InvoiceLineItemPeriod>,
62    pretax_credit_amounts: Option<Option<Vec<stripe_shared::InvoicesResourcePretaxCreditAmount>>>,
63    pricing: Option<Option<stripe_shared::BillingBillResourceInvoicingPricingPricing>>,
64    quantity: Option<Option<u64>>,
65    subscription: Option<Option<stripe_types::Expandable<stripe_shared::Subscription>>>,
66    taxes: Option<Option<Vec<stripe_shared::BillingBillResourceInvoicingTaxesTax>>>,
67}
68
69#[allow(
70    unused_variables,
71    irrefutable_let_patterns,
72    clippy::let_unit_value,
73    clippy::match_single_binding,
74    clippy::single_match
75)]
76const _: () = {
77    use miniserde::de::{Map, Visitor};
78    use miniserde::json::Value;
79    use miniserde::{Deserialize, Result, make_place};
80    use stripe_types::miniserde_helpers::FromValueOpt;
81    use stripe_types::{MapBuilder, ObjectDeser};
82
83    make_place!(Place);
84
85    impl Deserialize for InvoiceLineItem {
86        fn begin(out: &mut Option<Self>) -> &mut dyn Visitor {
87            Place::new(out)
88        }
89    }
90
91    struct Builder<'a> {
92        out: &'a mut Option<InvoiceLineItem>,
93        builder: InvoiceLineItemBuilder,
94    }
95
96    impl Visitor for Place<InvoiceLineItem> {
97        fn map(&mut self) -> Result<Box<dyn Map + '_>> {
98            Ok(Box::new(Builder {
99                out: &mut self.out,
100                builder: InvoiceLineItemBuilder::deser_default(),
101            }))
102        }
103    }
104
105    impl MapBuilder for InvoiceLineItemBuilder {
106        type Out = InvoiceLineItem;
107        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
108            Ok(match k {
109                "amount" => Deserialize::begin(&mut self.amount),
110                "currency" => Deserialize::begin(&mut self.currency),
111                "description" => Deserialize::begin(&mut self.description),
112                "discount_amounts" => Deserialize::begin(&mut self.discount_amounts),
113                "discountable" => Deserialize::begin(&mut self.discountable),
114                "discounts" => Deserialize::begin(&mut self.discounts),
115                "id" => Deserialize::begin(&mut self.id),
116                "invoice" => Deserialize::begin(&mut self.invoice),
117                "livemode" => Deserialize::begin(&mut self.livemode),
118                "metadata" => Deserialize::begin(&mut self.metadata),
119                "parent" => Deserialize::begin(&mut self.parent),
120                "period" => Deserialize::begin(&mut self.period),
121                "pretax_credit_amounts" => Deserialize::begin(&mut self.pretax_credit_amounts),
122                "pricing" => Deserialize::begin(&mut self.pricing),
123                "quantity" => Deserialize::begin(&mut self.quantity),
124                "subscription" => Deserialize::begin(&mut self.subscription),
125                "taxes" => Deserialize::begin(&mut self.taxes),
126                _ => <dyn Visitor>::ignore(),
127            })
128        }
129
130        fn deser_default() -> Self {
131            Self {
132                amount: Deserialize::default(),
133                currency: Deserialize::default(),
134                description: Deserialize::default(),
135                discount_amounts: Deserialize::default(),
136                discountable: Deserialize::default(),
137                discounts: Deserialize::default(),
138                id: Deserialize::default(),
139                invoice: Deserialize::default(),
140                livemode: Deserialize::default(),
141                metadata: Deserialize::default(),
142                parent: Deserialize::default(),
143                period: Deserialize::default(),
144                pretax_credit_amounts: Deserialize::default(),
145                pricing: Deserialize::default(),
146                quantity: Deserialize::default(),
147                subscription: Deserialize::default(),
148                taxes: Deserialize::default(),
149            }
150        }
151
152        fn take_out(&mut self) -> Option<Self::Out> {
153            let (
154                Some(amount),
155                Some(currency),
156                Some(description),
157                Some(discount_amounts),
158                Some(discountable),
159                Some(discounts),
160                Some(id),
161                Some(invoice),
162                Some(livemode),
163                Some(metadata),
164                Some(parent),
165                Some(period),
166                Some(pretax_credit_amounts),
167                Some(pricing),
168                Some(quantity),
169                Some(subscription),
170                Some(taxes),
171            ) = (
172                self.amount,
173                self.currency.take(),
174                self.description.take(),
175                self.discount_amounts.take(),
176                self.discountable,
177                self.discounts.take(),
178                self.id.take(),
179                self.invoice.take(),
180                self.livemode,
181                self.metadata.take(),
182                self.parent.take(),
183                self.period,
184                self.pretax_credit_amounts.take(),
185                self.pricing.take(),
186                self.quantity,
187                self.subscription.take(),
188                self.taxes.take(),
189            )
190            else {
191                return None;
192            };
193            Some(Self::Out {
194                amount,
195                currency,
196                description,
197                discount_amounts,
198                discountable,
199                discounts,
200                id,
201                invoice,
202                livemode,
203                metadata,
204                parent,
205                period,
206                pretax_credit_amounts,
207                pricing,
208                quantity,
209                subscription,
210                taxes,
211            })
212        }
213    }
214
215    impl Map for Builder<'_> {
216        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
217            self.builder.key(k)
218        }
219
220        fn finish(&mut self) -> Result<()> {
221            *self.out = self.builder.take_out();
222            Ok(())
223        }
224    }
225
226    impl ObjectDeser for InvoiceLineItem {
227        type Builder = InvoiceLineItemBuilder;
228    }
229
230    impl FromValueOpt for InvoiceLineItem {
231        fn from_value(v: Value) -> Option<Self> {
232            let Value::Object(obj) = v else {
233                return None;
234            };
235            let mut b = InvoiceLineItemBuilder::deser_default();
236            for (k, v) in obj {
237                match k.as_str() {
238                    "amount" => b.amount = FromValueOpt::from_value(v),
239                    "currency" => b.currency = FromValueOpt::from_value(v),
240                    "description" => b.description = FromValueOpt::from_value(v),
241                    "discount_amounts" => b.discount_amounts = FromValueOpt::from_value(v),
242                    "discountable" => b.discountable = FromValueOpt::from_value(v),
243                    "discounts" => b.discounts = FromValueOpt::from_value(v),
244                    "id" => b.id = FromValueOpt::from_value(v),
245                    "invoice" => b.invoice = FromValueOpt::from_value(v),
246                    "livemode" => b.livemode = FromValueOpt::from_value(v),
247                    "metadata" => b.metadata = FromValueOpt::from_value(v),
248                    "parent" => b.parent = FromValueOpt::from_value(v),
249                    "period" => b.period = FromValueOpt::from_value(v),
250                    "pretax_credit_amounts" => {
251                        b.pretax_credit_amounts = FromValueOpt::from_value(v)
252                    }
253                    "pricing" => b.pricing = FromValueOpt::from_value(v),
254                    "quantity" => b.quantity = FromValueOpt::from_value(v),
255                    "subscription" => b.subscription = FromValueOpt::from_value(v),
256                    "taxes" => b.taxes = FromValueOpt::from_value(v),
257                    _ => {}
258                }
259            }
260            b.take_out()
261        }
262    }
263};
264#[cfg(feature = "serialize")]
265impl serde::Serialize for InvoiceLineItem {
266    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
267        use serde::ser::SerializeStruct;
268        let mut s = s.serialize_struct("InvoiceLineItem", 18)?;
269        s.serialize_field("amount", &self.amount)?;
270        s.serialize_field("currency", &self.currency)?;
271        s.serialize_field("description", &self.description)?;
272        s.serialize_field("discount_amounts", &self.discount_amounts)?;
273        s.serialize_field("discountable", &self.discountable)?;
274        s.serialize_field("discounts", &self.discounts)?;
275        s.serialize_field("id", &self.id)?;
276        s.serialize_field("invoice", &self.invoice)?;
277        s.serialize_field("livemode", &self.livemode)?;
278        s.serialize_field("metadata", &self.metadata)?;
279        s.serialize_field("parent", &self.parent)?;
280        s.serialize_field("period", &self.period)?;
281        s.serialize_field("pretax_credit_amounts", &self.pretax_credit_amounts)?;
282        s.serialize_field("pricing", &self.pricing)?;
283        s.serialize_field("quantity", &self.quantity)?;
284        s.serialize_field("subscription", &self.subscription)?;
285        s.serialize_field("taxes", &self.taxes)?;
286
287        s.serialize_field("object", "line_item")?;
288        s.end()
289    }
290}
291impl stripe_types::Object for InvoiceLineItem {
292    type Id = stripe_shared::InvoiceLineItemId;
293    fn id(&self) -> &Self::Id {
294        &self.id
295    }
296
297    fn into_id(self) -> Self::Id {
298        self.id
299    }
300}
301stripe_types::def_id!(InvoiceLineItemId);