defmodule SimpleForm do @moduledoc false @type tag_name() :: String.t() @type content() :: [String.t() | element()] @type attribute() :: {key :: String.t(), value :: String.t()} @type element() :: {tag_name(), [attribute()], content()} @doc """ Checks if value is an element. ## Examples iex> SimpleForm.element?(true) false iex> SimpleForm.element?({"p", [{"class", "intro"}], [{"strong", [], ["Hello"]}, " world!"]}) true iex> SimpleForm.element?({"class", "strong"}) false iex> SimpleForm.element?("Hello World!") false """ @spec element?(term()) :: boolean() def element?({tag_name, attributes, content}) when is_binary(tag_name) and is_list(attributes) and is_list(content) do Enum.all?(attributes, &attribute?/1) and Enum.all?(content, &content?/1) end def element?(_), do: false @doc """ Checks if value is an attribute. ## Examples iex> SimpleForm.attribute?(true) false iex> SimpleForm.attribute?({"p", [{"class", "intro"}], [{"strong", [], ["Hello"]}, " world!"]}) false iex> SimpleForm.attribute?({"class", "strong"}) true iex> SimpleForm.attribute?("Hello World!") false """ @spec attribute?(term()) :: boolean() def attribute?({name, value}) when is_binary(name) and is_binary(value), do: true def attribute?(_), do: false @doc """ Checks if value is content. ## Examples iex> SimpleForm.content?(true) false iex> SimpleForm.content?({"p", [{"class", "intro"}], [{"strong", [], ["Hello"]}, " world!"]}) true iex> SimpleForm.content?({"class", "strong"}) false iex> SimpleForm.content?("Hello World!") true """ @spec content?(term()) :: boolean() def content?(content) when is_binary(content), do: true def content?(value), do: element?(value) end