Paraiso (paraiso v0.0.8)
The module of Paraiso
Link to this section Summary
Functions
第一引数paramsに対して第二引数propsで宣言されたバリデーションおよびサニタイズを実行する
オブジェクトのname/valueペアに対する、require/optionalおよびバリデーション仕様を宣言する
Link to this section Types
Specs
prop()
validator()
Specs
validator() :: :boolean | :int | nil | {:int, {:range, min :: integer(), max :: integer()}} | :string | {:string, {:range, min :: integer(), max :: integer()}} | {:string, {:regex, Regex.t()}} | String.t() | {:string_literals, [String.t()]} | {:string_as_atom, atom() | [atom()]} | {:object, [prop()]} | :object | {:array, validator()} | {:or, [validator()]} | {:custom, (value :: term() -> :ok | {:ok, any()} | {:error, reason :: atom()} | {:error, atom() | [atom() | integer()], atom()})}
validatorを表す型。prop/3
の引数validatorと同じ
Link to this section Functions
process(params, props)
Specs
第一引数paramsに対して第二引数propsで宣言されたバリデーションおよびサニタイズを実行する
返り値
検証成功の場合
{:ok, <サニタイズされた値>}
が返る
paramsでキーがStringの場合atomに変換される。またpropsに含まれないキーは削除される
iex> Paraiso.process(%{"a" => "abc", "b" => "cde"}, [Paraiso.prop(:a, :required, "abc")])
{:ok, %{a: "abc"}}
検証失敗の場合
{:error, <失敗箇所>, <失敗理由>}
が返る
あるpropで検証失敗した場合その時点で検証処理は打ち切られる。
prop(name, req_or_opt, validator)
Specs
prop( name :: atom(), required_or_optional :: :required | {:optional, default :: term()} | :optional, validator :: :boolean | nil | :int | {:int, {:range, min :: integer(), max :: integer()}} | :string | {:string, {:range, min :: integer(), max :: integer()}} | {:string, {:regex, Regex.t()}} | String.t() | {:string_literals, [String.t()]} | {:string_as_atom, atom() | [atom()]} | {:object, [prop()]} | :object | {:array, validator()} | {:or, [validator()]} | {:custom, (value :: term() -> :ok | {:ok, any()} | {:error, reason :: atom()} | {:error, atom() | [atom() | integer()], atom()})} ) :: prop()
オブジェクトのname/valueペアに対する、require/optionalおよびバリデーション仕様を宣言する
引数
- name: 宣言対象のname
- required_or_optional: このプロパティは必須かオプションか
- validator: バリデーション仕様
required_or_optional
:required
or {:optional, default :: term()} or :optional
:required
必須属性
iex> Paraiso.process(%{"a" => 1}, [Paraiso.prop(:a, :required, :int)])
{:ok, %{a: 1}}
iex> Paraiso.process(%{"b" => 1}, [Paraiso.prop(:a, :required, :int)])
{:error, :a, :required}
{:optional, default :: term()}
オプション属性。省略されていた場合defaultが補完される
iex> Paraiso.process(%{"a" => 1}, [Paraiso.prop(:a, {:optional, 0}, :int)])
{:ok, %{a: 1}}
iex> Paraiso.process(%{"b" => 1}, [Paraiso.prop(:a, {:optional, 0}, :int)])
{:ok, %{a: 0}}
:optional
オプション属性。省略されていた場合は補完されない
iex> Paraiso.process(%{"a" => 1}, [Paraiso.prop(:a, :optional, :int)])
{:ok, %{a: 1}}
iex> Paraiso.process(%{"b" => 1}, [Paraiso.prop(:a, :optional, :int)])
{:ok, %{}}
validator
:boolean
trueまたはfalseであるか検証
iex> Paraiso.process(%{"a" => true}, [Paraiso.prop(:a, :required, :boolean)])
{:ok, %{a: true}}
iex> Paraiso.process(%{"a" => false}, [Paraiso.prop(:a, :required, :boolean)])
{:ok, %{a: false}}
iex> Paraiso.process(%{"a" => "foo"}, [Paraiso.prop(:a, :required, :boolean)])
{:error, :a, :invalid}
nil
nilであるか検証
iex> Paraiso.process(%{"a" => nil}, [Paraiso.prop(:a, :required, nil)])
{:ok, %{a: nil}}
iex> Paraiso.process(%{"a" => false}, [Paraiso.prop(:a, :required, nil)])
{:error, :a, :invalid}
:int
整数型であるか検証
iex> Paraiso.process(%{"a" => 1}, [Paraiso.prop(:a, :required, :int)])
{:ok, %{a: 1}}
iex> Paraiso.process(%{"a" => "foo"}, [Paraiso.prop(:a, :required, :int)])
{:error, :a, :invalid}
{:int, {:range, min :: integer(), max :: integer()}}
min以上max以下の整数型であるか検証
iex> Paraiso.process(%{"a" => 0}, [Paraiso.prop(:a, :required, {:int, {:range, 0, 100}})])
{:ok, %{a: 0}}
iex> Paraiso.process(%{"a" => 100}, [Paraiso.prop(:a, :required, {:int, {:range, 0, 100}})])
{:ok, %{a: 100}}
iex> Paraiso.process(%{"a" => -1}, [Paraiso.prop(:a, :required, {:int, {:range, 0, 100}})])
{:error, :a, :invalid}
iex> Paraiso.process(%{"a" => 101}, [Paraiso.prop(:a, :required, {:int, {:range, 0, 100}})])
{:error, :a, :invalid}
iex> Paraiso.process(%{"a" => "foo"}, [Paraiso.prop(:a, :required, {:int, {:range, 0, 100}})])
{:error, :a, :invalid}
:string
文字列であるか検証
iex> Paraiso.process(%{"a" => "a"}, [Paraiso.prop(:a, :required, :string)])
{:ok, %{a: "a"}}
iex> Paraiso.process(%{"a" => 123}, [Paraiso.prop(:a, :required, :string)])
{:error, :a, :invalid}
{:string, {:range, min :: integer(), max :: integer()}}
長さmin以上max以下の文字列であるか検証
iex> Paraiso.process(%{"a" => "a"}, [Paraiso.prop(:a, :required, {:string, {:range, 1, 3}})])
{:ok, %{a: "a"}}
iex> Paraiso.process(%{"a" => "abc"}, [Paraiso.prop(:a, :required, {:string, {:range, 1, 3}})])
{:ok, %{a: "abc"}}
iex> Paraiso.process(%{"a" => ""}, [Paraiso.prop(:a, :required, {:string, {:range, 1, 3}})])
{:error, :a, :invalid}
iex> Paraiso.process(%{"a" => "abcd"}, [Paraiso.prop(:a, :required, {:string, {:range, 1, 3}})])
{:error, :a, :invalid}
iex> Paraiso.process(%{"a" => 1}, [Paraiso.prop(:a, :required, {:string, {:range, 1, 3}})])
{:error, :a, :invalid}
{:string, {:regex, Regex.t()}}
正規表現にマッチする文字列であるか検証
iex> Paraiso.process(%{"a" => "abc"}, [Paraiso.prop(:a, :required, {:string, {:regex, ~r/^abc/}})])
{:ok, %{a: "abc"}}
iex> Paraiso.process(%{"a" => "def"}, [Paraiso.prop(:a, :required, {:string, {:regex, ~r/^abc/}})])
{:error, :a, :invalid}
iex> Paraiso.process(%{"a" => 1}, [Paraiso.prop(:a, :required, {:string, {:regex, ~r/^abc/}})])
{:error, :a, :invalid}
String.t()
文字列リテラルと一致するか検証
iex> Paraiso.process(%{"a" => "abc"}, [Paraiso.prop(:a, :required, "abc")])
{:ok, %{a: "abc"}}
iex> Paraiso.process(%{"a" => "def"}, [Paraiso.prop(:a, :required, "abc")])
{:error, :a, :invalid}
iex> Paraiso.process(%{"a" => 1}, [Paraiso.prop(:a, :required, "abc")])
{:error, :a, :invalid}
{:string_literals, [String.t()]}
リスト中のいずれかの文字列リテラルと一致するか検証
iex> Paraiso.process(%{"a" => "abc"}, [Paraiso.prop(:a, :required, {:string_literals, ["abc", "def"]})])
{:ok, %{a: "abc"}}
iex> Paraiso.process(%{"a" => "def"}, [Paraiso.prop(:a, :required, {:string_literals, ["abc", "def"]})])
{:ok, %{a: "def"}}
iex> Paraiso.process(%{"a" => "ghi"}, [Paraiso.prop(:a, :required, {:string_literals, ["abc", "def"]})])
{:error, :a, :invalid}
iex> Paraiso.process(%{"a" => 1}, [Paraiso.prop(:a, :required, {:string_literals, ["abc", "def"]})])
{:error, :a, :invalid}
{:string_as_atom, atom() | [atom()]}
いずれかのアトムと一致するか検証。検証に成功した場合、結果の値はアトムとして保持される
iex> Paraiso.process(%{"a" => "abc"}, [Paraiso.prop(:a, :required, {:string_as_atom, :abc})])
{:ok, %{a: :abc}}
iex> Paraiso.process(%{"a" => "def"}, [Paraiso.prop(:a, :required, {:string_as_atom, :abc})])
{:error, :a, :invalid}
iex> Paraiso.process(%{"a" => "abc"}, [Paraiso.prop(:a, :required, {:string_as_atom, [:abc, :def]})])
{:ok, %{a: :abc}}
iex> Paraiso.process(%{"a" => "def"}, [Paraiso.prop(:a, :required, {:string_as_atom, [:abc, :def]})])
{:ok, %{a: :def}}
iex> Paraiso.process(%{"a" => "ghi"}, [Paraiso.prop(:a, :required, {:string_as_atom, [:abc, :def]})])
{:error, :a, :invalid}
iex> Paraiso.process(%{"a" => 1}, [Paraiso.prop(:a, :required, {:string_as_atom, [:abc, :def]})])
{:error, :a, :invalid}
{:object, [prop()]}
対象オブジェクトをvalueとした場合にParaiso.process(value, [prop()])
に相当する検証をする
検証に成功した場合: map()が値部分に格納される
検証に失敗した場合: {:error, [<エラーが発生した要素までのパス>], reason}
が返る
iex> Paraiso.process(
...> %{"a" => %{"b" => "c"}},
...> [Paraiso.prop(:a, :required, {:object, [Paraiso.prop(:b, :required, "c")]})]
...> )
{:ok, %{a: %{b: "c"}}}
iex> Paraiso.process(
...> %{"a" => %{"b" => "d"}},
...> [Paraiso.prop(:a, :required, {:object, [Paraiso.prop(:b, :required, "c")]})]
...> )
{:error, [:a, :b], :invalid}
iex> Paraiso.process(
...> %{"a" => "b"},
...> [Paraiso.prop(:a, :required, {:object, [Paraiso.prop(:b, :required, "c")]})]
...> )
{:error, :a, :invalid}
:object
オブジェクト型であるか検証
検証に成功した場合: map()が値部分に格納される(キーはatom()に変換されない)
検証に失敗した場合: {:error, [<エラーが発生した要素までのパス>], reason}
が返る
iex> Paraiso.process(
...> %{"a" => %{"b" => "c"}},
...> [Paraiso.prop(:a, :required, :object)]
...> )
{:ok, %{a: %{"b" => "c"}}}
iex> Paraiso.process(
...> %{"a" => 1},
...> [Paraiso.prop(:a, :required, :object)]
...> )
{:error, :a, :invalid}
{:array, validator()}
リスト中の要素に対してvalidator()に基づいて検証する
検証に失敗した場合、 {:error, [<エラーが発生した要素までのパス>], reason}
が返る
iex> Paraiso.process(
...> %{"a" => [1, 2, 3]},
...> [Paraiso.prop(:a, :required, {:array, :int})]
...> )
{:ok, %{a: [1, 2, 3]}}
iex> Paraiso.process(
...> %{"a" => ["foo", 2, 3]},
...> [Paraiso.prop(:a, :required, {:array, :int})]
...> )
{:error, [:a, 0], :invalid}
iex> Paraiso.process(
...> %{"a" => [%{"b" => 1}, %{"b" => "c"}]},
...> [Paraiso.prop(:a, :required, {:array, {:object, [Paraiso.prop(:b, :required, :int)]}})]
...> )
{:error, [:a, 1, :b], :invalid}
iex> Paraiso.process(
...> %{"a" => "foo"},
...> [Paraiso.prop(:a, :required, {:array, {:object, [Paraiso.prop(:b, :required, :int)]}})]
...> )
{:error, :a, :invalid}
{:or, [validator()]}
リスト中のいずれかで成功するか検証する
iex> Paraiso.process(
...> %{"a" => true},
...> [Paraiso.prop(:a, :required, {:or, [:boolean, "foo"]})]
...> )
{:ok, %{a: true}}
iex> Paraiso.process(
...> %{"a" => "foo"},
...> [Paraiso.prop(:a, :required, {:or, [:boolean, "foo"]})]
...> )
{:ok, %{a: "foo"}}
iex> Paraiso.process(
...> %{"a" => "bar"},
...> [Paraiso.prop(:a, :required, {:or, [:boolean, "foo"]})]
...> )
{:error, :a, :invalid}
iex> Paraiso.process(
...> %{"a" => %{"b" => "c"}},
...> [
...> Paraiso.prop(
...> :a,
...> :required,
...> {:or,
...> [
...> nil,
...> {:object,
...> [
...> Paraiso.prop(:b, :required, :string)
...> ]}
...> ]}
...> )
...> ]
...> )
{:ok, %{a: %{b: "c"}}}
iex> Paraiso.process(
...> %{"a" => nil},
...> [
...> Paraiso.prop(
...> :a,
...> :required,
...> {:or,
...> [
...> nil,
...> {:object,
...> [
...> Paraiso.prop(:b, :required, :string)
...> ]}
...> ]}
...> )
...> ]
...> )
{:ok, %{a: nil}}
{:custom, (value :: term() -> :ok | {:error, reason :: atom()})}
関数で検証する。関数の仕様は以下
検証に成功した場合、:ok
を返す。また、成功で、バリデーション済みオブジェクトを返したければ {:ok, <オブジェクト> :: any()}
を返す
検証に失敗した場合、{:error, <失敗理由> :: atom()}
を返す。また、失敗で、失敗したパスを返したければ {:error, <失敗したパス情報> :: atom() | [atom() | integer()], <失敗理由> :: atom()}
を返す
iex> Paraiso.process(
...> %{"a" => 1},
...> [
...> Paraiso.prop(
...> :a,
...> :required,
...> {:custom, fn v -> if(v == 1, do: :ok, else: {:error, :invalid}) end}
...> )
...> ]
...> )
{:ok, %{a: 1}}
iex> Paraiso.process(
...> %{"a" => 2},
...> [
...> Paraiso.prop(
...> :a,
...> :required,
...> {:custom, fn v -> if(v == 1, do: :ok, else: {:error, :invalid}) end}
...> )
...> ]
...> )
{:error, :a, :invalid}
iex> Paraiso.process(
...> %{"a" => %{"b" => 1}},
...> [
...> Paraiso.prop(
...> :a,
...> :required,
...> {:custom, fn %{"b" => v} -> if(v == 1, do: {:ok, %{b: v}}, else: {:error, :b, :invalid}) end}
...> )
...> ]
...> )
{:ok, %{a: %{b: 1}}}
iex> Paraiso.process(
...> %{"a" => %{"b" => 2}},
...> [
...> Paraiso.prop(
...> :a,
...> :required,
...> {:custom, fn %{"b" => v} -> if(v == 1, do: {:ok, %{b: v}}, else: {:error, :b, :invalid}) end}
...> )
...> ]
...> )
{:error, [:a, :b], :invalid}
iex> Paraiso.process(
...> %{"a" => %{"b" => %{"c" => 2}}},
...> [
...> Paraiso.prop(
...> :a,
...> :required,
...> {:custom, fn %{"b" => %{"c" => v}} -> if(v == 1, do: {:ok, %{b: %{c: v}}}, else: {:error, [:b, :c], :invalid}) end}
...> )
...> ]
...> )
{:error, [:a, :b, :c], :invalid}