# `EctoCommons.StringValidator`
[🔗](https://github.com/achedeuzot/ecto_commons/blob/v0.3.7/lib/validators/string.ex#L1)

This module provides validation for String / Text values

The following validators are available:

  * `validate_has_prefix/3` which will check if a given field is prefixed
    by some given fixed or dynamic string

## Example:

    # Simple prefix
    iex> types = %{token: :string}
    iex> params = %{token: "private|some-random-string-id"}
    iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
    ...> |> validate_has_prefix(:token, prefix: "private")
    #Ecto.Changeset<action: nil, changes: %{token: "private|some-random-string-id"}, errors: [], data: %{}, valid?: true, ...>

    # Prefix with separator
    iex> types = %{token: :string}
    iex> params = %{token: "private|some-random-string-id"}
    iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
    ...> |> validate_has_prefix(:token, prefix: "private", separator: "|")
    #Ecto.Changeset<action: nil, changes: %{token: "private|some-random-string-id"}, errors: [], data: %{}, valid?: true, ...>

    # Wrong prefix
    iex> types = %{token: :string}
    iex> params = %{token: "private|some-random-string-id"}
    iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
    ...> |> validate_has_prefix(:token, prefix: "provider")
    #Ecto.Changeset<action: nil, changes: %{token: "private|some-random-string-id"}, errors: [token: {"is not prefixed by %{prefix}.", [validation: :has_prefix]}], data: %{}, valid?: false, ...>

    # Correct prefix but wrong separator
    iex> types = %{token: :string}
    iex> params = %{token: "private|some-random-string-id"}
    iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
    ...> |> validate_has_prefix(:token, prefix: "private", separator: "_")
    #Ecto.Changeset<action: nil, changes: %{token: "private|some-random-string-id"}, errors: [token: {"is not prefixed by %{prefix}.", [validation: :has_prefix]}], data: %{}, valid?: false, ...>

    # Dynamic prefix from function which is correct
    iex> types = %{token: :string}
    iex> params = %{token: "private|some-random-string-id"}
    iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
    ...> |> validate_has_prefix(:token, prefix: fn _chgst, _opts -> "private" end)
    #Ecto.Changeset<action: nil, changes: %{token: "private|some-random-string-id"}, errors: [], data: %{}, valid?: true, ...>

    # Dynamic prefix from another changeset field
    iex> types = %{token: :string, provider: :string}
    iex> params = %{token: "iamsvc|some-random-string-id", provider: "iamsvc"}
    iex> changeset = Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
    ...> |> validate_has_prefix(:token, prefix: fn chgst, _opts -> Ecto.Changeset.get_field(chgst, :provider) end)
    iex> changeset.changes.provider
    "iamsvc"
    iex> changeset.changes.token
    "iamsvc|some-random-string-id"
    iex> changeset.valid?
    true

    # Dynamic prefix from another changeset field
    iex> types = %{token: :string, provider: :string}
    iex> params = %{token: "some-random-string-id", provider: nil}
    iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
    ...> |> validate_has_prefix(:token, prefix: fn chgst, _opts -> Ecto.Changeset.get_field(chgst, :provider) end)
    #Ecto.Changeset<action: nil, changes: %{token: "some-random-string-id"}, errors: [], data: %{}, valid?: true, ...>

    # Dynamic prefix from function, which fails
    iex> types = %{token: :string}
    iex> params = %{token: "private|some-random-string-id"}
    iex> Ecto.Changeset.cast({%{}, types}, params, Map.keys(types))
    ...> |> validate_has_prefix(:token, prefix: fn _chgst, _opts -> "test" end)
    #Ecto.Changeset<action: nil, changes: %{token: "private|some-random-string-id"}, errors: [token: {"is not prefixed by %{prefix}.", [validation: :has_prefix]}], data: %{}, valid?: false, ...>

# `validate_has_prefix`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
