Skip to content

streaming-standardization: add stream-based process + process_file convenience - #3

Merged
rferreira merged 1 commit into
mainfrom
change/streaming-standardization
Apr 29, 2026
Merged

rferreira merged 1 commit into
mainfrom
change/streaming-standardization

Conversation

@rferreira

@rferreira rferreira commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the streaming standardization for scanii-ruby per STREAMING_STANDARDIZATION.md §3.8.

What changed

  • New canonical methods: process(io, filename:, ...) and process_async(io, filename:, ...) accept any IO-like object (duck-typed on read(n)). Both File and StringIO work.
  • New path convenience methods: process_file(path, ...) and process_async_file(path, ...) open the file in binary mode and delegate to the stream-based methods. These replace the old process(path) form.
  • Deprecated aliases: process(String_path, ...) and process_async(String_path, ...) still work but emit a runtime warn directing callers to process_file / process_async_file. Will be removed in a future major version.
  • True streaming: lib/scanii/multipart.rb refactored to stream_encode — builds prologue + epilogue as binary Strings, chains them around the caller's IO via a ChainedIO class, and sends the body via Net::HTTP#body_stream= with an explicit Content-Length. File content is never fully buffered.

Version bump: 1.0.1 → 1.1.0

Per API_VERSIONING_POLICY.md: the change shape is additive (new public methods, no removals, deprecated aliases kept). Additive changes ship as minor version bumps. No existing consumer code breaks; deprecated callers get a warn but keep working.

Tests

  • Unit: StringIO path, File.open IO path, process_file path, deprecated process(path) emits warning, process_async variants
  • Integration: all above plus live scanii-cli runs confirming end-to-end streaming works
  • 57 runs, 135 assertions, 0 failures, 3 expected skips (UUID fixture + callback require newer scanii-cli build — self-skip per workspace convention)
  • rubocop: no offenses

Test plan

  • CI passes on Linux / macOS / Windows × Ruby 3.4 + 4.0
  • Scan a real file via process_file — result is clean or flagged as expected
  • Scan a StringIO via process(StringIO.new(...), filename: "test.bin") — same result
  • Call old process(path) — confirm deprecation warning appears on stderr

🤖 Generated with Claude Code

…nvenience

Add IO-based process(io, filename:, ...) and process_async(io, filename:, ...)
as the canonical stream input methods. process_file / process_async_file are
thin path-based convenience wrappers that open the file in binary mode and
delegate. The old process(path_string) / process_async(path_string) signatures
remain as deprecated aliases that emit a runtime warn.

Internally, lib/scanii/multipart.rb now builds the multipart body as a
ChainedIO (prologue StringIO + caller IO + epilogue StringIO) and returns the
content-length so Net::HTTP can set it explicitly when using body_stream=.
File content is never fully buffered.

Version bump 1.0.1 -> 1.1.0 (additive: new public methods, no removals).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rferreira
rferreira merged commit 5ec3c5a into main Apr 29, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant