Skip to content

Commit 36c1fa1

Browse files
authored
Merge pull request #5 from LoyaltyNZ/feature/fix-nested-nil
Cope gracefully with errors when path contains a nil value
2 parents 50c00dd + 00858bd commit 36c1fa1

2 files changed

Lines changed: 29 additions & 3 deletions

File tree

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: elixir
22
elixir:
3-
- 1.6
3+
- 1.8
4+
- 1.9
45
otp_release:
5-
- 19.3
6-
- 20.2
6+
- 22.0
77
sudo: false

lib/json_pointer.ex

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ defmodule JSONPointer do
8080
8181
iex> JSONPointer.get( %{ "contents" => [ "milk", "butter", "eggs" ]}, "/contents/4" )
8282
{:error, "index out of bounds: 4"}
83+
84+
iex> JSONPointer.get( %{ "fridge" => %{ "cake" => true }, "stove" => nil}, "/stove/cake" )
85+
{:error, "parent token not found: cake"}
86+
87+
8388
"""
8489
@spec get(container, pointer) :: {:ok, t} | error_message
8590
def get(obj, pointer, options \\ @default_options) do
@@ -98,6 +103,10 @@ defmodule JSONPointer do
98103
true
99104
iex> JSONPointer.get!( %{}, "/fridge/milk" )
100105
** (ArgumentError) json pointer key not found: fridge
106+
107+
iex> JSONPointer.get!( %{ "fridge" => %{ "cake" => true }, "stove" => nil}, "/stove/cake" )
108+
** (ArgumentError) parent token not found: cake
109+
101110
"""
102111
@spec get!(container, pointer, options) :: t | no_return
103112
def get!(obj, pointer, options \\ @default_options) do
@@ -116,6 +125,9 @@ defmodule JSONPointer do
116125
117126
iex> JSONPointer.has?( %{ "milk" => true, "butter" => false}, "/cornflakes" )
118127
false
128+
129+
iex> JSONPointer.has?( %{ "fridge" => %{ "cake" => true }, "stove" => nil}, "/stove/cake" )
130+
false
119131
"""
120132
@spec has?(container, pointer, options) :: boolean
121133
def has?(obj, pointer, options \\ @default_options) do
@@ -132,6 +144,8 @@ defmodule JSONPointer do
132144
iex> JSONPointer.test( %{ "milk" => "skimmed", "butter" => false}, "/milk", "skimmed" )
133145
{:ok, %{ "milk" => "skimmed", "butter" => false} }
134146
147+
iex> JSONPointer.test( %{ "fridge" => %{ "cake" => true }, "stove" => nil}, "/stove/cake", "true" )
148+
{:error, "parent token not found: cake"}
135149
"""
136150
@spec test(container, pointer, t, options) :: {:ok, t} | error_message
137151
def test(obj, pointer, value, options \\ @default_options) do
@@ -154,6 +168,9 @@ defmodule JSONPointer do
154168
iex> JSONPointer.test!( %{ "milk" => "skimmed", "butter" => false}, "/butter", "unsalted" )
155169
** (ArgumentError) not equal
156170
171+
172+
iex> JSONPointer.test!( %{ "fridge" => %{ "cake" => true }, "stove" => nil}, "/stove/cake", "true" )
173+
** (ArgumentError) parent token not found: cake
157174
"""
158175
@spec test!(container, pointer, t, options) :: t | no_return
159176
def test!(obj, pointer, value, options \\ @default_options) do
@@ -172,6 +189,9 @@ defmodule JSONPointer do
172189
173190
iex> JSONPointer.remove( %{"fridge" => %{ "milk" => true, "butter" => true}}, "/fridge/sandwich" )
174191
{:error, "json pointer key not found: sandwich", %{ "butter" => true, "milk" => true}}
192+
193+
iex> JSONPointer.remove( %{ "fridge" => %{ "cake" => true }, "stove" => nil}, "/stove/cake" )
194+
{:error, "parent token not found: cake", nil}
175195
"""
176196
@spec remove(container, pointer, options) :: {:ok, t, removed} | error_message
177197
def remove(object, pointer, options \\ @default_options) do
@@ -190,6 +210,7 @@ defmodule JSONPointer do
190210
191211
iex> JSONPointer.set( %{"milk"=>"full"}, "/milk", "empty")
192212
{:ok, %{"milk" => "empty"}, "full"}
213+
193214
"""
194215
@spec set(container, pointer, t, options) :: {:ok, t, existing} | error_message
195216
def set(obj, pointer, value, options \\ @default_options) do
@@ -921,6 +942,11 @@ defmodule JSONPointer do
921942
{:ok, result, nil}
922943
end
923944

945+
# stop walking the container if we hit a nil value
946+
defp walk_container(_operation, _parent, nil, token, _tokens, _value, _options) do
947+
{:error, "parent token not found: #{token}", nil}
948+
end
949+
924950
defp next_result(
925951
{:ok, _existing},
926952
operation,

0 commit comments

Comments
 (0)