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
127                _ => <dyn Visitor>::ignore(),
128            })
129        }
130
131        fn deser_default() -> Self {
132            Self {
133                amount: Deserialize::default(),
134                currency: Deserialize::default(),
135                description: Deserialize::default(),
136                discount_amounts: Deserialize::default(),
137                discountable: Deserialize::default(),
138                discounts: Deserialize::default(),
139                id: Deserialize::default(),
140                invoice: Deserialize::default(),
141                livemode: Deserialize::default(),
142                metadata: Deserialize::default(),
143                parent: Deserialize::default(),
144                period: Deserialize::default(),
145                pretax_credit_amounts: Deserialize::default(),
146                pricing: Deserialize::default(),
147                quantity: Deserialize::default(),
148                subscription: Deserialize::default(),
149                taxes: Deserialize::default(),
150            }
151        }
152
153        fn take_out(&mut self) -> Option<Self::Out> {
154            let (
155                Some(amount),
156                Some(currency),
157                Some(description),
158                Some(discount_amounts),
159                Some(discountable),
160                Some(discounts),
161                Some(id),
162                Some(invoice),
163                Some(livemode),
164                Some(metadata),
165                Some(parent),
166                Some(period),
167                Some(pretax_credit_amounts),
168                Some(pricing),
169                Some(quantity),
170                Some(subscription),
171                Some(taxes),
172            ) = (
173                self.amount,
174                self.currency.take(),
175                self.description.take(),
176                self.discount_amounts.take(),
177                self.discountable,
178                self.discounts.take(),
179                self.id.take(),
180                self.invoice.take(),
181                self.livemode,
182                self.metadata.take(),
183                self.parent.take(),
184                self.period,
185                self.pretax_credit_amounts.take(),
186                self.pricing.take(),
187                self.quantity,
188                self.subscription.take(),
189                self.taxes.take(),
190            )
191            else {
192                return None;
193            };
194            Some(Self::Out {
195                amount,
196                currency,
197                description,
198                discount_amounts,
199                discountable,
200                discounts,
201                id,
202                invoice,
203                livemode,
204                metadata,
205                parent,
206                period,
207                pretax_credit_amounts,
208                pricing,
209                quantity,
210                subscription,
211                taxes,
212            })
213        }
214    }
215
216    impl Map for Builder<'_> {
217        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
218            self.builder.key(k)
219        }
220
221        fn finish(&mut self) -> Result<()> {
222            *self.out = self.builder.take_out();
223            Ok(())
224        }
225    }
226
227    impl ObjectDeser for InvoiceLineItem {
228        type Builder = InvoiceLineItemBuilder;
229    }
230
231    impl FromValueOpt for InvoiceLineItem {
232        fn from_value(v: Value) -> Option<Self> {
233            let Value::Object(obj) = v else {
234                return None;
235            };
236            let mut b = InvoiceLineItemBuilder::deser_default();
237            for (k, v) in obj {
238                match k.as_str() {
239                    "amount" => b.amount = FromValueOpt::from_value(v),
240                    "currency" => b.currency = FromValueOpt::from_value(v),
241                    "description" => b.description = FromValueOpt::from_value(v),
242                    "discount_amounts" => b.discount_amounts = FromValueOpt::from_value(v),
243                    "discountable" => b.discountable = FromValueOpt::from_value(v),
244                    "discounts" => b.discounts = FromValueOpt::from_value(v),
245                    "id" => b.id = FromValueOpt::from_value(v),
246                    "invoice" => b.invoice = FromValueOpt::from_value(v),
247                    "livemode" => b.livemode = FromValueOpt::from_value(v),
248                    "metadata" => b.metadata = FromValueOpt::from_value(v),
249                    "parent" => b.parent = FromValueOpt::from_value(v),
250                    "period" => b.period = FromValueOpt::from_value(v),
251                    "pretax_credit_amounts" => {
252                        b.pretax_credit_amounts = FromValueOpt::from_value(v)
253                    }
254                    "pricing" => b.pricing = FromValueOpt::from_value(v),
255                    "quantity" => b.quantity = FromValueOpt::from_value(v),
256                    "subscription" => b.subscription = FromValueOpt::from_value(v),
257                    "taxes" => b.taxes = FromValueOpt::from_value(v),
258
259                    _ => {}
260                }
261            }
262            b.take_out()
263        }
264    }
265};
266#[cfg(feature = "serialize")]
267impl serde::Serialize for InvoiceLineItem {
268    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
269        use serde::ser::SerializeStruct;
270        let mut s = s.serialize_struct("InvoiceLineItem", 18)?;
271        s.serialize_field("amount", &self.amount)?;
272        s.serialize_field("currency", &self.currency)?;
273        s.serialize_field("description", &self.description)?;
274        s.serialize_field("discount_amounts", &self.discount_amounts)?;
275        s.serialize_field("discountable", &self.discountable)?;
276        s.serialize_field("discounts", &self.discounts)?;
277        s.serialize_field("id", &self.id)?;
278        s.serialize_field("invoice", &self.invoice)?;
279        s.serialize_field("livemode", &self.livemode)?;
280        s.serialize_field("metadata", &self.metadata)?;
281        s.serialize_field("parent", &self.parent)?;
282        s.serialize_field("period", &self.period)?;
283        s.serialize_field("pretax_credit_amounts", &self.pretax_credit_amounts)?;
284        s.serialize_field("pricing", &self.pricing)?;
285        s.serialize_field("quantity", &self.quantity)?;
286        s.serialize_field("subscription", &self.subscription)?;
287        s.serialize_field("taxes", &self.taxes)?;
288
289        s.serialize_field("object", "line_item")?;
290        s.end()
291    }
292}
293impl stripe_types::Object for InvoiceLineItem {
294    type Id = stripe_shared::InvoiceLineItemId;
295    fn id(&self) -> &Self::Id {
296        &self.id
297    }
298
299    fn into_id(self) -> Self::Id {
300        self.id
301    }
302}
303stripe_types::def_id!(InvoiceLineItemId);