# `FeedReader.XMLResourceLimits`

Accounts SAX events before a format handler retains their data.

These limits prevent large or pathological feeds from causing unbounded
parser memory use or work. Although SAX input is incremental, handlers still
retain feed metadata, attributes, and the current item's content. This module
makes parsing fail with a resource-limit error before those retained values
exceed their budgets.

Call `account_event/3` before updating parser state. Set the scope to `:feed`
while collecting feed metadata and to `:item` for the current item; starting
each item resets its byte budget. The defaults bound a document to 1,000,000
events, depth 256, 128 attributes per element, 64 KiB per attribute, 1 MiB of
feed metadata, and 4 MiB per item. Limits can be overridden with matching
`:max_*` options; invalid values use the defaults.

# `limit_error`

```elixir
@type limit_error() :: {:resource_limit, atom(), non_neg_integer()}
```

# `scope`

```elixir
@type scope() :: :none | :feed | :item
```

# `t`

```elixir
@type t() :: %FeedReader.XMLResourceLimits{
  depth: term(),
  events: term(),
  feed_metadata_bytes: term(),
  item_bytes: term(),
  max_attribute_bytes: term(),
  max_attributes_per_element: term(),
  max_feed_metadata_bytes: term(),
  max_item_bytes: term(),
  max_xml_depth: term(),
  max_xml_events: term(),
  scope: term()
}
```

# `account_event`

```elixir
@spec account_event(t(), atom(), term()) ::
  {:ok, t()} | {:error, limit_error() | :invalid_sax_event}
```

Checks one Saxy event and returns updated accounting or a stable limit error.

# `new`

```elixir
@spec new(keyword()) :: t()
```

Creates an accounting state using defaults or valid non-negative limits.

# `set_scope`

```elixir
@spec set_scope(t(), scope()) :: t()
```

Selects which retained-data budget subsequent SAX events consume.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
