Current section
Files
Jump to
Current section
Files
lib/retort/request.ex
defmodule Retort.Request do
@moduledoc """
A JSON-RPC [Request object](http://www.jsonrpc.org/specification#request_object)
"""
alias Retort.Response
@derive [Poison.Encoder]
defstruct jsonrpc: "2.0",
id: nil,
method: nil,
params: nil
@type t :: %__MODULE__{
jsonrpc: String.t,
id: integer | String.t | nil,
method: String.t,
params: [...] | map | nil
}
@doc """
Decodes a JSON-encoded string back to an `t`.
# Decode method without parameters
iex> {:ok, request} = Retort.Request.from_string(
...> ~S|{"jsonrpc": "2.0", "id": 1, "method": "index"}|
...> )
iex> request
%Retort.Request{jsonrpc: "2.0", id: 1, method: "index"}
# Decode method with positional arguments
iex> {:ok, request} = Retort.Request.from_string(
...> ~S|{"jsonrpc": "2.0", "id": 2, "method": "show", "params": [1]}|
...> )
iex> request
%Retort.Request{jsonrpc: "2.0", id: 2, method: "show", params: [1]}
# Decode method with named arguments
iex> {:ok, request} = Retort.Request.from_string(
...> ~S|{"jsonrpc": "2.0", "id": 3, "method": "create", "params": {"name": "Alice"}}|
...> )
iex> request
%Retort.Request{jsonrpc: "2.0", id: 3, method: "create", params: %{"name" => "Alice"}}
# Decode with empty request is invalid
iex> Retort.Request.from_string("")
{:error, :invalid}
# Decode with missing fields is OK
iex> {:ok, request} = Retort.Request.from_string("{}")
iex> request
%Retort.Request{}
# Decode with syntax error is invalid
iex> {:error, {:invalid, token}} = Retort.Request.from_string(
...> ~S|{"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]|
...> )
iex> token
"p"
# Proper handling of *all* return values
# See http://www.jsonrpc.org/specification#examples
response = case Retort.Request.from_string(encoded_request) do
{:ok, request = %Retort.Request{}} ->
response_for(request)
{:error, :invalid} ->
%Retort.Response{
error: %Retort.Response.Error{
code: -32600,
message: "Invalid Request"
}
}
{:error, {:invalid, token}} ->
%Retort.Response{
error: %Retort.Response.Error{
code: -32700,
message: "Parse error"
}
}
end
encoded_response = Poison.encode!(response)
"""
@spec from_string(String.t) :: {:ok, t} | {:error, :invalid} | {:error, {:invalid, String.t}}
def from_string(string) when is_binary(string) do
Poison.decode(string, as: %__MODULE__{})
end
@doc """
Constructs `Interpreter.Rpc.Response.t` with same `id` as the given response.
iex> request = %Retort.Request{id: 1}
iex> response = Retort.Request.to_response(request)
iex> response.id == request.id
true
"""
@spec to_response(t) :: Response.t
def to_response(%__MODULE__{id: id}), do: %Response{id: id}
end