Current section
Files
Jump to
Current section
Files
lib/structs/version.ex
defmodule Manganese.CoreKit.Structs.Version do
@moduledoc """
A SemVer version.
## Deserialization
*See `from_string/1`*
## Serialization
The version struct implements the `String.Chars` protocol.
## Manipulation
- see `increment/2`
"""
alias Manganese.CoreKit.Structs
alias Manganese.CoreKit.Enumerations
@typedoc """
"""
@type t :: %Structs.Version{
major: non_neg_integer,
minor: non_neg_integer,
patch: non_neg_integer
}
defstruct [
major: 0,
minor: 0,
patch: 0
]
# Creation
@doc """
"""
@spec new :: t
def new, do: %Structs.Version{}
# Deserialization
@doc """
"""
@spec from_string(String.t) :: t
def from_string(string) do
components =
String.split(string, ".")
|> Enum.map(&Integer.parse/1)
[ major, minor, patch ] = components
%Structs.Version{
major: major,
minor: minor,
patch: patch
}
end
# Serialization
@type t_external :: String.t
# Manipulation
@doc """
"""
@spec increment(t, Enumerations.VersionType.t) :: t
def increment(version, version_type \\ :patch) do
case version_type do
:major ->
%Structs.Version{
major: version.major + 1
}
:minor ->
%Structs.Version{
major: version.major,
minor: version.minor + 1
}
:patch ->
%Structs.Version{
major: version.major,
minor: version.minor,
patch: version.patch + 1
}
end
end
# Ecto type
@behaviour Ecto.Type
@impl Ecto.Type
def type, do: :string
@impl Ecto.Type
def cast(%Structs.Version{} = version), do: { :ok, version }
def cast(string) when is_binary(string), do: { :ok, from_string string }
def cast(nil), do: { :ok, nil }
def cast(_), do: :error
@impl Ecto.Type
def load(string) when is_binary(string), do: { :ok, from_string string }
def load(nil), do: { :ok, nil }
def load(_), do: :error
@impl Ecto.Type
def dump(%Structs.Version{} = version), do: { :ok, to_string version }
def dump(nil), do: { :ok, nil }
def dump(_), do: :error
end
defimpl String.Chars, for: Manganese.CoreKit.Structs.Version do
def to_string(version) do
"#{version.major}.#{version.minor}.#{version.patch}"
end
end