Skip to content

Instantly share code, notes, and snippets.

@gfmurphy
Last active December 28, 2017 14:04
Show Gist options
  • Save gfmurphy/baa693863686446fa20d8b5678787904 to your computer and use it in GitHub Desktop.
Save gfmurphy/baa693863686446fa20d8b5678787904 to your computer and use it in GitHub Desktop.
Request path protocol spike
defprotocol JsonApiClient.RequestPath do
@moduledoc """
The `JsonApiClient.RequestPath` protocol provides a single function to be implemented that maps
a given Elixir term to a string representation of an url path.
"""
@doc """
Converts `term` to a string representation of a given path.
"""
@spec to_path(term()) :: String.t
def to_path(term)
end
defimpl JsonApiClient.RequestPath, for: BitString do
def to_path(term) when is_binary(term), do: String.replace_leading(term, "/", "")
end
defimpl JsonApiClient.RequestPath, for: JsonApiClient.Resource do
alias JsonApiClient.Resource
def to_path(%Resource{type: type, id: id}) do
[type, id]
|> Enum.reject(&is_nil/1)
|> Enum.join("/")
end
end
defimpl JsonApiClient.RequestPath, for: List do
alias JsonApiClient.Resource
alias JsonApiClient.RequestPath.BitString, as: BitStringImpl
alias JsonApiClient.RequestPath.JsonApiClient.Resource, as: ResourceImpl
def to_path([]), do: ""
def to_path(term) when is_list(term) do
term
|> Enum.map_join("/", fn
%Resource{} = r -> ResourceImpl.to_path(r)
t when is_binary(t) -> BitStringImpl.to_path(t)
end)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment