@@ -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