Skip to content

struct_cop will make you treat data in your structs with respect!

License

Notifications You must be signed in to change notification settings

HarenBroog/struct_cop

Repository files navigation

StructCop

Build Status Coverage Status Hex.pm Hex.pm

StructCop is a library that was aimed to introduce data correctness and type coercion into Elixir structs. It also simplifies building valid structs with smart constructors.

Getting Started

Installation

Add struct_copto your list of dependencies in mix.exs:

def deps do
  [
    {:struct_cop, "~> 0.2.0"}
  ]
end

Contract

Define a contract for given entity. We will be describing a single measure for sport activity:

defmodule Measurement do
  use StructCop

  contract do
    field :elevation, :float
    field :lat, :float
    field :lng, :float
    field :tracked_at, :utc_datetime_usec
  end

  def validate(changeset) do
    import Ecto.Changeset

    changeset
    |> validate_required([:tracked_at, :lat, :lng])
    |> validate_number(:lat, greater_than_or_equal_to: -90, less_than_or_equal_to: 90)
    |> validate_number(:lng, greater_than_or_equal_to: -180, less_than_or_equal_to: 180)
  end
end

Usage

From that moment we can:

> Measurement.new!(lat: 10, lng: 20, tracked_at: DateTime.utc_now())
%Measurement{
  elevation: nil,
  lat: 10.0,
  lng: 20.0,
  tracked_at: ~U[2019-12-28 18:36:01.625656Z]
}

It also casts fields from binaries:

> Measurement.new!(lat: "52.409538", lng: "16.931992", tracked_at: "2019-12-28T18:30:43.288080+00:00")
%Measurement{
  elevation: nil,
  lat: 52.409538,
  lng: 16.931992,
  tracked_at: ~U[2019-12-28 18:30:43.288080Z]
}

Passing invalid attributes raises an ArgumentError:

> Measurement.new!(lat: "not_a_float", lng: 200.10)
** (ArgumentError) cast failed for %Measurement{elevation: nil, lat: nil, lng: nil, tracked_at: nil}:
params:
  %{"lat" => "not_a_float", "lng" => 200.1}
errors:
  [lng: {"must be less than or equal to %{number}", [validation: :number, kind: :less_than_or_equal_to, number: 180]}, tracked_at: {"can't be blank", [validation: :required]}, lat: {"is invalid", [type: :float, validation: :cast]}]

    (struct_cop) lib/struct_cop.ex:47: StructCop.cast!/2

Credits

About

struct_cop will make you treat data in your structs with respect!

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages