              $
              """x
 
+  @type t :: %Semver{major: integer, minor: integer, patch: integer, prerelease: [String.t], build: [String.t]}
   defstruct major: 0, minor: 0, patch: 0, prerelease: [], build: []
 
   @doc """
   Gets the version string of the module.
   """
+  @spec version() :: String.t
   def version, do: @vsn
 
   @doc """
   Validates that `version` is a valid Semver string.
   """
+  @spec is_valid(String.t) :: boolean
   def is_valid(version), do: version =~ @pattern
 
   @doc """
   Parses `version` into a `Semver` struct.
   """
+  @spec parse(String.t) :: {:ok, t} | {:error, :invalid}
   def parse(version) do
     cond do
       is_valid(version) -> parse_valid(version)

  Parses a version string into a `Semver` struct. If `version` is not a valid version string, it
  raises `Semver.Error`.
  """
  def parse!(version) do
    case parse(version) do
      {:ok, retval} -> retval

  @doc """
  Converts a `Semver` struct into a version string.
  """
  @spec to_string(t) :: String.t
  def to_string(struct) do
    "#{struct.major}.#{struct.minor}.#{struct.patch}"
    |> append_prerelease(struct)
