Evil and Powerful Protocols for Elixir
Protocols are just modules! And sometimes you just want to do module things in protocols. And when you're in control of both the protocol and the module you're implementing for, colocating the code in the module you're writing just makes sense. This library does this automatically for you.
useProtossdefprotocolMyProtocoldo# this works like a normal protocol forward definition.deffun_must_be_implemented(argument)# delegations forward to the passed module. Currently# this is not currently runtime-checked, but it will be # in the future under a flag.## call as:# `MyProtocol.from_json(MyStruct, ...)`#defdelegatefrom_json(module,argument)# after block separates protocol code from module codeafter# struct protocol implementations MUST implement these# extra callbacks:@callbackextra_callback()::term# this can be called directly as: `MyProtocol.root_function()`defroot_functiondo:okendendIn your (struct) protocols, the implementation of MyProtocol from above
would look like this.
defmoduleMyStructdodefstruct[:value]useMyProtocol@implMyProtocoldeffun_must_be_implemented(%__MODULE__{value: value}),do: value# note the arity change!@implMyProtocoldeffrom_json(%{"value"=>value}),do: %__MODULE__{value: value}@implMyProtocoldefextra_callback,do: "I was required to implement this"endIn order to get proper formatting, you should add the following option to your .formatter.exs
locals_without_parens: [defdelegate: 1]
The package is available on hex and can be installed by adding protoss to your
list of dependencies in mix.exs:
defdepsdo[{:protoss,"~> 0.2"}]endDocumentation can be found at https://hexdocs.pm/protoss.