-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extra config to set custom machine ID and start time (#1)
Changes in this PR: * Config validation helpers * Add options to set machine_id and start_time * Bump version to 0.2.0
- Loading branch information
Showing
7 changed files
with
226 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
defmodule Sonyflakex.Config do | ||
@moduledoc """ | ||
Configuration validation helpers | ||
""" | ||
|
||
@doc """ | ||
Sets default value for an option if option is not set | ||
in option list. Default value is set from a callback. | ||
Args: | ||
- opts: Configuration options. | ||
- option_name: Key for configuration option being validated. | ||
- default_callback: Function that returns a default value. | ||
""" | ||
@spec set_default(keyword(), atom(), (-> any())) :: {:ok, keyword()} | ||
def set_default(opts, option_name, default_callback) do | ||
case Keyword.fetch(opts, option_name) do | ||
{:ok, _value} -> | ||
{:ok, opts} | ||
|
||
:error -> | ||
new_opts = Keyword.put(opts, option_name, default_callback.()) | ||
{:ok, new_opts} | ||
end | ||
end | ||
|
||
@doc """ | ||
Validates option value is an integer. This is checked only | ||
if value is set. | ||
""" | ||
@spec validate_is_integer(keyword(), atom()) :: | ||
{:error, {:non_integer, atom(), any()}} | {:ok, keyword()} | ||
def validate_is_integer(opts, option_name) do | ||
case Keyword.fetch(opts, option_name) do | ||
{:ok, value} when is_integer(value) -> | ||
{:ok, opts} | ||
|
||
{:ok, value} -> | ||
{:error, {:non_integer, option_name, value}} | ||
|
||
:error -> | ||
{:ok, opts} | ||
end | ||
end | ||
|
||
@doc ~S""" | ||
Validates option value integer can be set as a binary | ||
in a field with a limited number of bits. | ||
Args: | ||
- opts: Configuration options | ||
- option_name: Key for configuration option being validated. | ||
- max_bits: Maximum number of bits that would fit the option value. | ||
""" | ||
@spec validate_bit_option_length(keyword(), atom(), non_neg_integer()) :: | ||
{:error, {:value_too_big, atom(), integer()}} | {:ok, keyword()} | ||
def validate_bit_option_length(opts, option_name, max_bits) do | ||
case Keyword.fetch(opts, option_name) do | ||
{:ok, value} -> | ||
if value_fits_in_bits(value, max_bits) do | ||
{:ok, opts} | ||
else | ||
{:error, {:value_too_big, option_name, value}} | ||
end | ||
|
||
:error -> | ||
{:ok, opts} | ||
end | ||
end | ||
|
||
@doc ~S""" | ||
Checks if integer value binary representatino would fit in a number of bits. | ||
## Examples | ||
iex> Sonyflakex.Config.value_fits_in_bits(255, 8) | ||
true | ||
""" | ||
@spec value_fits_in_bits(integer(), non_neg_integer()) :: boolean() | ||
def value_fits_in_bits(value, length_bits) do | ||
<<max::integer-size(length_bits + 1)>> = <<1::size(1), 0::size(length_bits)>> | ||
value < max | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
defmodule Sonyflakex.ConfigTest do | ||
use ExUnit.Case, async: true | ||
doctest Sonyflakex.Config | ||
|
||
alias Sonyflakex.Config | ||
|
||
describe "set_default/3" do | ||
test "sets integer value from callback function return if option is not set" do | ||
{:ok, opts} = Config.set_default([age: 42], :size, fn -> 200 end) | ||
assert {:ok, 200} = Keyword.fetch(opts, :size) | ||
end | ||
|
||
test "doesn't change option value if option is set" do | ||
{:ok, opts} = Config.set_default([age: 42], :age, fn -> 200 end) | ||
assert {:ok, 42} = Keyword.fetch(opts, :age) | ||
end | ||
end | ||
|
||
describe "validate_is_integer/2" do | ||
test "returns ok if value is not set" do | ||
assert {:ok, []} = Config.validate_is_integer([], :size) | ||
end | ||
|
||
test "returns ok if value set is integer" do | ||
assert {:ok, [size: 170]} = Config.validate_is_integer([size: 170], :size) | ||
end | ||
|
||
test "returns error if value set is not integer" do | ||
assert {:error, {:non_integer, :size, :not_an_integer}} = | ||
Config.validate_is_integer([size: :not_an_integer], :size) | ||
end | ||
end | ||
|
||
describe "value_fits_in_bits/2" do | ||
test "checks input value fits input number of bits" do | ||
assert Config.value_fits_in_bits(1, 1) == true | ||
assert Config.value_fits_in_bits(2, 1) == false | ||
assert Config.value_fits_in_bits(2, 2) == true | ||
assert Config.value_fits_in_bits(0, 1) == true | ||
assert Config.value_fits_in_bits(0b10000000, 7) == false | ||
assert Config.value_fits_in_bits(0b10000000, 8) == true | ||
end | ||
end | ||
|
||
describe "validate_bit_option_length/3" do | ||
test "keeps option with input value if is valid" do | ||
{:ok, opts} = Config.validate_bit_option_length([age: 42], :age, 8) | ||
assert {:ok, 42} = Keyword.fetch(opts, :age) | ||
end | ||
|
||
test "indicates validation error if input integer value can't fit in the max number of bits" do | ||
{:error, which} = Config.validate_bit_option_length([age: 42], :age, 3) | ||
assert which == {:value_too_big, :age, 42} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters