Skip to content

Commit

Permalink
Fix to keep json_parser config
Browse files Browse the repository at this point in the history
  • Loading branch information
pojiro committed Jun 6, 2023
1 parent 5c9b5f3 commit d7080f5
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 34 deletions.
7 changes: 7 additions & 0 deletions lib/slipstream/configuration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ defmodule Slipstream.Configuration do
type: :atom,
default: Slipstream.Serializer.PhoenixSocketV2Serializer
],
json_parser: [
doc: """
A JSON parser module which exports at least `encode!/1` and `decode!/1`.
""",
type: :atom,
default: Jason
],
reconnect_after_msec: [
doc: """
A list of times to reference for trying reconnection when
Expand Down
8 changes: 5 additions & 3 deletions lib/slipstream/connection/impl.ex
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,18 @@ defmodule Slipstream.Connection.Impl do

defp encode(%Message{} = message, state) do
module = state.config.serializer
module.encode!(message)
module.encode!(message, json_parser: state.config.json_parser)
end

# try decoding as json
def decode_message({encoding, message}, state)
when encoding in [:text, :binary] and is_binary(message) do
module = state.config.serializer

try do
module.decode!(message, opcode: encoding)
module.decode!(message,
opcode: encoding,
json_parser: state.config.json_parser
)
rescue
# coveralls-ignore-start
_ in [Serializer.DecodeError] ->
Expand Down
45 changes: 22 additions & 23 deletions lib/slipstream/serializer/phoenix_socket_v2_serializer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ defmodule Slipstream.Serializer.PhoenixSocketV2Serializer do
@push 0
@reply 1

def encode!(binary, opts \\ [])

def encode!(%Message{payload: {:binary, data}} = message, _opts) do
try do
join_ref = to_string(message.join_ref)
Expand Down Expand Up @@ -44,7 +42,7 @@ defmodule Slipstream.Serializer.PhoenixSocketV2Serializer do
end
end

def encode!(%Message{} = message, opts) do
def encode!(%Message{} = message, [json_parser: json_parser] = _opts) do
try do
[
message.join_ref,
Expand All @@ -53,50 +51,51 @@ defmodule Slipstream.Serializer.PhoenixSocketV2Serializer do
message.event,
message.payload
]
|> Jason.encode!(opts)
|> json_parser.encode!()
rescue
# coveralls-ignore-start
exception in [Jason.EncodeError] ->
exception in [Protocol.UndefinedError] ->
reraise(
Serializer.EncodeError,
[message: exception.message],
[message: inspect(exception)],
__STACKTRACE__
)

# coveralls-ignore-stop

exception in [Protocol.UndefinedError] ->
# coveralls-ignore-start
maybe_json_parser_exception ->
reraise(
Serializer.EncodeError,
[message: inspect(exception)],
[message: maybe_json_parser_exception.message],
__STACKTRACE__
)

# coveralls-ignore-stop
end
end

def decode!(binary, opts) do
def decode!(binary, [opcode: opcode, json_parser: json_parser] = _opts) do
try do
case Keyword.fetch!(opts, :opcode) do
:text -> decode_text!(binary)
case opcode do
:text -> decode_text!(binary, json_parser: json_parser)
:binary -> decode_binary!(binary)
end
rescue
# coveralls-ignore-start
exception in [Jason.DecodeError, KeyError] ->
# for binary doesn't match decode_binary!/1 function pattern match
exception in [FunctionClauseError] ->
reraise(
Serializer.DecodeError,
[message: exception.message],
[message: FunctionClauseError.message(exception)],
__STACKTRACE__
)

# coveralls-ignore-stop

exception in [FunctionClauseError] ->
# coveralls-ignore-start
maybe_json_parser_exception ->
reraise(
Serializer.DecodeError,
[message: FunctionClauseError.message(exception)],
[message: inspect(maybe_json_parser_exception)],
__STACKTRACE__
)

# coveralls-ignore-stop
end
end

Expand Down Expand Up @@ -140,8 +139,8 @@ defmodule Slipstream.Serializer.PhoenixSocketV2Serializer do
}
end

defp decode_text!(binary) do
case Jason.decode!(binary) do
defp decode_text!(binary, json_parser: json_parser) do
case json_parser.decode!(binary) do
[join_ref, ref, topic, event, payload | _] ->
%Message{
join_ref: join_ref,
Expand Down
19 changes: 11 additions & 8 deletions test/slipstream/serializer/phoenix_socket_v2_serializer_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,35 @@ defmodule Slipstream.Serializer.PhoenixSocketV2SerializerTest do
"""

import Slipstream.Serializer.PhoenixSocketV2Serializer,
only: [encode!: 1, decode!: 2]
only: [encode!: 2, decode!: 2]

alias Slipstream.Message

describe "encode!/1 raise Slipstream.Serializer.EncodeError" do
describe "encode!/2 raise Slipstream.Serializer.EncodeError" do
test "when binary payload, topic size is greater than 255 bytes" do
assert_raise(Slipstream.Serializer.EncodeError, fn ->
encode!(%Message{
payload: {:binary, _data = ""},
topic: String.duplicate("a", 256)
})
encode!(
%Message{
payload: {:binary, _data = ""},
topic: String.duplicate("a", 256)
},
json_parser: Jason
)
end)
end

test "when payload won't be encoded" do
assert_raise(Slipstream.Serializer.EncodeError, fn ->
# tuple cannot be encoded to JSON
encode!(%Message{payload: {"a"}})
encode!(%Message{payload: {"a"}}, json_parser: Jason)
end)
end
end

describe "decode!/1 raise Slipstream.Serializer.DecodeError" do
test "binary does't match function arugment pattern" do
assert_raise(Slipstream.Serializer.DecodeError, fn ->
decode!(<<>>, opcode: :binary)
decode!(<<>>, opcode: :binary, json_parser: Jason)
end)
end
end
Expand Down

0 comments on commit d7080f5

Please sign in to comment.