我有一种行为来抽象解析各种 Phoenix 端点的 URL 查询参数。它看起来像这样:
defmodule Query do
@callback from_query_params(params :: %{optional(String.t()) => any()}) ::
{:ok, parsed :: struct} | {:error, reason :: atom}
end
一个简单的实现如下所示:
defmodule SearchQuery do
@moduledoc "Parses URL query params for search endpoint"
@behaviour Query
@enforce_keys [:search_term]
defstruct @enforce_keys
@typespec t :: %__MODULE__{search_term: String.t()}
@impl Query
def from_query_params(%{"query" => query}) when query != "" do
{:ok, %__MODULE__{search_term: query}}
end
def from_query_params(_), do: {:error, :missing_search_term}
end
我在这里真正想说的是:
- 实现模块应该提供一个结构(调用它
t()
) - 成功类型
from_query_params/1
应该使用那个structt()
,而不仅仅是任何 struct
我怀疑 Elixir 类型规范语言中没有办法表达这一点,但我很高兴被证明是错误的。