• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thanos / codecs / 9766ea6e9a941cc88c7469b1120f2d4eefc4a409-PR-1

13 Jun 2026 03:24PM UTC coverage: 94.853%. First build
9766ea6e9a941cc88c7469b1120f2d4eefc4a409-PR-1

Pull #1

github

thanos
fix: address review findings across tests, docs, API, and build

Tests:
- Add compressible-data round-trip tests for all 5 codecs
- Add blosc2 typed-data tests (float64/int32 with typesize > 1)
- Add blosc2 byte-shuffle round-trip tests with uniform data
- Add property tests for zero-fill and repeated-string data
- Add option effectiveness tests (zstd level, bzip2 block_size,
  blosc2 clevel)
- Add corrupt-input tests for lz4, snappy, bzip2
- Add codec_registry register/3 failure path tests
- Add codec_unavailable encode/decode path tests
- Add doctests for ExCodecs, ExCodecs.Error, ExCodecs.Compression
- Remove tests for removed options (LZ4 level, bzip2 work_factor,
  blosc2 :bit shuffle)

Docs:
- Fix available_codecs/0 ordering to alphabetical across all modules
- Fix codec_info/1 doc to show {:ok, %Codec{}} return shape
- Fix ExCodecs.Codec behaviour example to show NIF.wrap/2 pattern
- Fix README: Elixir 1.17+, OTP 26+, Rust 1.85+; remove "production-
  quality" and "maximum throughput" claims; describe precompiled NIFs
  accurately; update options table (LZ4 non-configurable, bzip2
  block_size only, blosc2 shuffle :none/:byte only, no blocksize/
  numthreads); add benchmarks Mix alias

Dead code removal:
- Remove Error.from_nif/2 (unused, duplicates NIF.wrap/2) (M3)
- Remove config/config.exs :codecs list (M1)
- Remove config/test.exs registry_table override (M2)
- Remove prompts/prompt-0.1.0md → rename to prompt-0.1.0.md (N1)

Build:
- Switch native.ex from use Rustler to use RustlerPrecompiled
  with version, base_url, nif_versions, and targets (H3)
- Move rustler dep to :dev/:test only; rustler_precompiled is primary
- Add checksum-*.exs to mix.exs package files
- Move force_build to dev/test config only; strip from prod config
- Remove bzip2_codec work_factor NIF parameter
- Remove lz4_codec level NIF parameter
- Remove blosc2_codec bitshuffle (aliased to byte shuffle)
Pull Request #1: The ExCodecs v0.1.0 implementation is complete. Here's a summary of e…

129 of 136 new or added lines in 12 files covered. (94.85%)

129 of 136 relevant lines covered (94.85%)

233.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.67
/lib/ex_codecs/error.ex
1
defmodule ExCodecs.Error do
2
  @moduledoc """
3
  Standardized error types for ExCodecs.
4

5
  All ExCodecs functions return `{:ok, result}` or `{:error, reason}` tuples.
6
  The `reason` will be one of the atoms defined in this module, or a structured
7
  error when additional context is needed.
8
  """
9

10
  @type error_reason ::
11
          :unsupported_codec
12
          | :codec_unavailable
13
          | :invalid_data
14
          | :invalid_options
15
          | :compression_failed
16
          | :decompression_failed
17
          | :nif_not_loaded
18

19
  @type t :: %__MODULE__{
20
          reason: error_reason(),
21
          message: String.t(),
22
          codec: atom() | nil,
23
          details: term() | nil
24
        }
25

26
  defexception [:reason, :message, :codec, :details]
27

28
  @doc """
29
  Creates a new error struct.
30

31
      iex> error = ExCodecs.Error.new(:unsupported_codec)
32
      iex> error.reason
33
      :unsupported_codec
34
      iex> error.message
35
      "The specified codec is not supported"
36
      iex> error.codec
37
      nil
38

39
      iex> error = ExCodecs.Error.new(:invalid_options, codec: :zstd)
40
      iex> error.codec
41
      :zstd
42
  """
43
  @spec new(error_reason(), keyword()) :: t()
44
  def new(reason, opts \\ []) do
45
    %__MODULE__{
66✔
46
      reason: reason,
47
      message: Keyword.get(opts, :message, default_message(reason)),
48
      codec: Keyword.get(opts, :codec),
49
      details: Keyword.get(opts, :details)
50
    }
51
  end
52

53
  @doc """
54
  Creates an `{:error, ExCodecs.Error.t()}` tuple.
55

56
      iex> {:error, error} = ExCodecs.Error.error(:unsupported_codec)
57
      iex> error.reason
58
      :unsupported_codec
59
  """
60
  @spec error(error_reason(), keyword()) :: {:error, t()}
61
  def error(reason, opts \\ []) do
62
    {:error, new(reason, opts)}
63
  end
64

65
  defp default_message(:unsupported_codec), do: "The specified codec is not supported"
10✔
66
  defp default_message(:codec_unavailable), do: "The codec is known but not available at runtime"
4✔
67
  defp default_message(:invalid_data), do: "The input data is invalid for this codec"
12✔
68
  defp default_message(:invalid_options), do: "The provided options are invalid"
23✔
69
  defp default_message(:compression_failed), do: "Compression failed"
4✔
70
  defp default_message(:decompression_failed), do: "Decompression failed"
11✔
71
  defp default_message(:nif_not_loaded), do: "The native NIF library is not loaded"
1✔
72
  defp default_message(reason), do: "Error: #{reason}"
1✔
73

74
  @impl true
NEW
75
  def message(%__MODULE__{message: message}), do: message
×
76

77
  @doc """
78
  Checks if an error matches a specific reason.
79

80
      iex> {:error, error} = ExCodecs.Error.error(:unsupported_codec)
81
      iex> ExCodecs.Error.matches?({:error, error}, :unsupported_codec)
82
      true
83
      iex> ExCodecs.Error.matches?({:error, error}, :invalid_data)
84
      false
85
  """
86
  @spec matches?({:error, t()}, error_reason()) :: boolean()
87
  def matches?({:error, %__MODULE__{reason: reason}}, reason), do: true
2✔
88
  def matches?(_, _), do: false
3✔
89
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc