VFS.StreamOptions (VFS v0.1.0)

Copy Markdown View Source

Helper module for backend authors implementing stream_read/3. Applies the documented options (:chunk_size, :byte_range, :line_range) to a binary content and returns a chunk Stream — or {:error, :einval} for malformed options.

Every backend whose stream_read/3 returns bytes (memory-backed, postgres-backed, S3-backed, blob-store-backed) wants the same option handling. Centralizing it here means:

  • No backend silently ignores documented options.
  • Validation is uniform — :einval triggers identical conditions across every backend, which the conformance suite enforces.
  • Bug fixes propagate to every backend (e.g. the :line_range last < first validation).

Usage from a defimpl VFS.Mountable block:

def stream_read(%MyBackend{} = b, path, opts) do
  case fetch_content(b, path) do
    {:ok, content} ->
      case VFS.StreamOptions.apply(content, opts) do
        {:ok, stream} -> {:ok, stream, b}
        {:error, kind} -> {:error, VFS.Error.new(kind, path: path)}
      end

    :error ->
      {:error, VFS.Error.new(:enoent, path: path)}
  end
end

Summary

Functions

Apply :chunk_size, :byte_range, and :line_range options to content, returning {:ok, chunk_stream} or {:error, :einval}.

Functions

apply(content, opts)

@spec apply(
  binary(),
  keyword()
) :: {:ok, Enumerable.t(binary())} | {:error, :einval}

Apply :chunk_size, :byte_range, and :line_range options to content, returning {:ok, chunk_stream} or {:error, :einval}.

Order of operations: byte slice → line slice → chunk. So byte_range: {0, 100}, line_range: {1, 5} means "first 100 bytes, then take the first 5 lines of those." Mixing both is unusual but the order is documented for predictability.