Class: Ucode::CodeChart::Fetcher

Inherits:
Object
  • Object
show all
Defined in:
lib/ucode/code_chart/fetcher.rb

Overview

Feature-facing PDF fetch + cache + integrity check for one Unicode block's Code Charts PDF. Wraps Fetch::Http for the network I/O and adds:

* sha256 sidecar — recomputed on every cache hit; mismatch
raises {Ucode::CodeChartChecksumError} so tampering is
detected before extraction consumes a corrupt PDF.
* typed errors — HTTP 4xx raises {Ucode::CodeChartNotFoundError}
without retry; 5xx still retried by {Fetch::Http}.
* idempotency — cache hit returns the existing path without a
network call when both the PDF and the sha256 sidecar exist.

Single CodeChart-feature-facing API: Fetcher#fetch(block:). The HTTP layer stays a private collaborator; new transports (mirror, S3) subclass + register, no caller change.

Instance Method Summary collapse

Constructor Details

#initialize(version:, http: nil) ⇒ Fetcher

Returns a new instance of Fetcher.

Parameters:

  • version (String)

    UCD version, used as the cache namespace.

  • http (Module<Ucode::Fetch::Http>, nil) (defaults to: nil)

    injectable for tests. nil = the real Fetch::Http.



27
28
29
30
# File 'lib/ucode/code_chart/fetcher.rb', line 27

def initialize(version:, http: nil)
  @version = version
  @http = http || Fetch::Http
end

Instance Method Details

#fetch(block:) ⇒ Pathname

Returns the cached PDF path. Downloads when missing.

Parameters:

Returns:

  • (Pathname)

    the cached PDF path. Downloads when missing.

Raises:



38
39
40
# File 'lib/ucode/code_chart/fetcher.rb', line 38

def fetch(block:)
  fetch_by_first_cp(block_first_cp: block.range_first, block_id: block.id)
end

#fetch_by_first_cp(block_first_cp:, **_kwargs) ⇒ Pathname

Alternative entrypoint when the caller has only the first codepoint. Same semantics as #fetch.

Parameters:

  • block_first_cp (Integer)
  • block_id (String, nil)

    for error context only.

Returns:

  • (Pathname)


48
49
50
51
52
53
54
# File 'lib/ucode/code_chart/fetcher.rb', line 48

def fetch_by_first_cp(block_first_cp:, **_kwargs)
  path = per_block_path(block_first_cp)
  return path if cache_valid?(path)

  download(block_first_cp)
  path
end