# `Errow.String`
[🔗](https://github.com/kuku/errow/blob/v0.1.0/lib/errow/string.ex#L1)

An immutable, continuous-memory string array implementing the Apache Arrow `Utf8` columnar format.

Under the hood, data is organized in three buffers:
  1. **Offsets buffer** (`offsets`): a continuous binary of 32-bit signed integers in little-endian.
  2. **Data buffer** (`data`): a continuous binary containing the concatenated UTF-8 string bytes.
  3. **Validity bitmap** (`validity`): a bitstring tracking null (`nil`) values (1 bit per element).

## Features
* **O(1) Random Access**: Slicing and indexing (`array[i]`) use `binary_part/3` without copying memory.
* **Full Protocol Integration**: Implements `Enumerable`, `Collectable`, and `Access`.
* **Arrow Compatible**: 100% byte-for-byte compliant with the Apache Arrow specification.

# `t`

```elixir
@type t() :: %Errow.String{
  data: binary(),
  length: non_neg_integer(),
  null_count: non_neg_integer(),
  offsets: binary(),
  validity: bitstring()
}
```

# `append`

```elixir
@spec append(t(), binary() | nil) :: t()
```

Appends a string or `nil` to the array.

# `buffer_byte_size`

```elixir
@spec buffer_byte_size(t()) :: non_neg_integer()
```

Returns the byte size of the continuous data buffer.

# `delete_at`

```elixir
@spec delete_at(t(), integer()) :: t()
```

Deletes the element at index `idx`.

# `fetch`

```elixir
@spec fetch(t(), integer() | Range.t()) :: {:ok, any()} | :error
```

Fetches the element at the given index or a slice specified by a range.
Supports negative indices (e.g. `-1` for the last element).

# `from_list`

```elixir
@spec from_list(Enumerable.t()) :: t()
```

Builds an `Errow.String` array from a list or enumerable of strings and optional `nil`s.

# `get`

```elixir
@spec get(t(), integer(), any()) :: binary() | nil | any()
```

Gets the value at index `idx` or returns `default` if out of bounds.

# `join`

```elixir
@spec join(t(), binary(), keyword()) :: binary()
```

Joins the strings in the array with the given separator.
Null values are skipped by default.

# `max`

```elixir
@spec max(t(), keyword()) :: binary() | nil
```

Finds the lexicographically largest string in the array.

# `min`

```elixir
@spec min(t(), keyword()) :: binary() | nil
```

Finds the lexicographically smallest string in the array.

# `new`

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

Creates a new empty `Errow.String` array.

# `null?`

```elixir
@spec null?(t(), integer()) :: boolean()
```

Checks if the value at the given index is null (`nil`).

# `null_count`

```elixir
@spec null_count(t()) :: non_neg_integer()
```

Returns the count of null values.

# `replace_at`

```elixir
@spec replace_at(t(), integer(), binary() | nil) :: t()
```

Replaces the element at the given index with a new string or `nil`.

# `size`

```elixir
@spec size(t()) :: non_neg_integer()
```

Returns the number of elements in the array.

# `to_list`

```elixir
@spec to_list(t()) :: [binary() | nil]
```

Converts the `Errow.String` array into a standard Elixir list.

# `total_bytes`

```elixir
@spec total_bytes(t()) :: non_neg_integer()
```

Returns the sum of byte lengths of all strings in the array.

---

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