Skip to content

Large structures that are not flattened cause buffer overflow / convencience functions for flattened types. #271

Closed

Description

@Exotik850

Currently, large structs that are flattened into a Vec<FieldType> have the issue of needing to iterate the collection of fields to find a specific one, for example with the quickbooks-xsd crate I'm working on:

pub enum InvoiceTypeContent {
    Id(String),
    SyncToken(String),
    MetaData(ModificationMetaDataType),
    CustomField(CustomFieldType),
    AttachableRef(AttachableRefType),
    DocNumber(String),
    TxnDate(String),
    DepartmentRef(ReferenceTypeType),
    CurrencyRef(ReferenceTypeType),
    ExchangeRate(f64),
    PrivateNote(String),
    TxnStatus(String),
    LinkedTxn(LinkedTxnType),
    Line(LineType),
    TxnTaxDetail(TxnTaxDetailType),
    TxnSource(String),
    TaxFormType(String),
    TaxFormNum(String),
... (96 total variants)

is the field type for the InvoiceType struct:

pub struct InvoiceType {
    pub domain: Option<String>,
    pub status: Option<EntityStatusEnumType>,
    pub sparse: Option<bool>,
    pub content: Vec<InvoiceTypeContent>,
}

Which requires the end-user to iterate the items of the content field. This would be mitigated by not flattening the generated structure, resulting in the following code:

pub struct InvoiceType {
    pub id: Option<String>,
    pub custom_field: Option<String>,
    pub private_note: Option<String>,
    ...
}

However, on the basic example of deserializing an example invoice here it causes a stack overflow

I propose adding the logic to allow for functions like fn $field_name(&self) -> Option<T> to flattened structures to allow for more ergonomic use of the generated code.
This would allow us to replace all instances of

let note: Option<String> = invoice.content.find(|f| match f {
  InvoiceFieldType::PrivateNote(note) => Some(note),
  _ => None
});

with

let note: Option<String> = invoice.private_note();

OR to fix the stack overflow issue for larger structs, however this seems like a more in-depth issue that would take a lot more effort

Activity

  1. Bergmann89 commented on May 26, 2026

    @Bergmann89
    Owner

    Hey @Exotik850,

    the stack overflow with complex schemas and the resulting large structures are known issues. I already have an idea to use something like a Vec<Box<dyn Deserializer>> to store the active deserializers instead of bubbling through the entire stack every time, which should eliminate the issue and might also improve performance. But as you already suggested, this is not a trivial task.

    Implementing the helper methods you suggested should be relatively straightforward. We could just add a new render step for them, so users can enable it when needed. Unfortunately, my time is currently very limited. I can try to hack something together with Copilot’s support, or maybe you’d be willing to contribute a suitable solution if I guide you a bit?

    Best, Bergmann89.

  2. Exotik850 commented on May 26, 2026

    @Exotik850
    Author

    I can put something together later on when I get home, I'll post a PR so that you can review it

    Thanks for the hard work 👍🏻

  3. Bergmann89 commented on May 26, 2026

    @Bergmann89
    Owner

    Thanks for the hard work 👍🏻

    Thank you for contributing to the project 🙂

  4. Bergmann89 commented on Jun 22, 2026

    @Bergmann89
    Owner

    Closed by #279

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions