Skip to content

Commit 3231989

Browse files
committed
Add Torque.get_many_defaults/3 for 0.1.9
Variant of get_many_nil/2 that takes %{path => default} and returns %{path => value_or_default}. Saves callers from the awkward two-call pattern: paths = Map.keys(defaults) values = Torque.get_many_nil(doc, paths) Enum.zip(paths, values) |> Map.new(fn {p, nil} -> {p, Map.get(defaults, p)}; pv -> pv end) Now a single call: Torque.get_many_defaults(doc, %{ "/user/id" => 0, "/user/name" => "anonymous", "/created_at" => nil }) Returns a same-shape map with parsed values, falling back to the provided defaults for missing/null fields. Same nil/missing indistinguishability semantics as get_many_nil/2. Pure-Elixir wrapper around the existing NIF (get_many_nil/2); no new Rust code, no NIF dispatch overhead beyond the one get_many_nil call. Has an embedded doctest exercised by the test suite. D1's two other plan items resolved on inspection: - 'aarch64 baseline variant in release matrix' -- aarch64 v8 is universal across consumer CPUs, no v2 distinction needed. The matrix already ships aarch64-apple-darwin + aarch64-linux-gnu. - 'property test for float round-trip precision' -- already covered by test/property_test.exs (35 properties, 626 lines) with a json_scalar generator that includes float(-1000..1000), encoded/decoded through the round-trip suite. README and mix.exs version both bumped to 0.1.9.
1 parent 7632c15 commit 3231989

3 files changed

Lines changed: 43 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Add to your `mix.exs`:
2020
```elixir
2121
def deps do
2222
[
23-
{:torque, "~> 0.1.8"}
23+
{:torque, "~> 0.1.9"}
2424
]
2525
end
2626
```

lib/torque.ex

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,47 @@ defmodule Torque do
298298
Torque.Native.get_many_nil(doc, paths)
299299
end
300300

301+
@doc """
302+
Extracts multiple values from a parsed document with per-path defaults.
303+
304+
Takes a map of `%{path => default}` and returns a map of the same shape
305+
where each value is either the parsed value or the supplied default (if
306+
the path is missing).
307+
308+
More ergonomic than the two-call `get_many_nil/2` + `Enum.map` pattern
309+
when consumers need defaults at the call site.
310+
311+
Equivalent to:
312+
313+
get_many_nil(doc, Map.keys(defaults))
314+
|> then(&Enum.zip(Map.keys(defaults), &1))
315+
|> Map.new(fn {p, nil} -> {p, Map.get(defaults, p)}; pv -> pv end)
316+
317+
Note: a parsed JSON `null` at the path is indistinguishable from a missing
318+
field (same as `get_many_nil/2`) — both substitute the default.
319+
320+
## Examples
321+
322+
iex> {:ok, doc} = Torque.parse(~s({"a":1,"b":null}))
323+
iex> Torque.get_many_defaults(doc, %{"/a" => 0, "/b" => 0, "/c" => "missing"})
324+
%{"/a" => 1, "/b" => 0, "/c" => "missing"}
325+
"""
326+
@doc group: :parse_get
327+
@spec get_many_defaults(reference(), %{binary() => term()}) ::
328+
%{binary() => term()}
329+
def get_many_defaults(doc, defaults)
330+
when is_reference(doc) and is_map(defaults) do
331+
paths = Map.keys(defaults)
332+
values = Torque.Native.get_many_nil(doc, paths)
333+
334+
paths
335+
|> Enum.zip(values)
336+
|> Map.new(fn
337+
{path, nil} -> {path, Map.get(defaults, path)}
338+
pv -> pv
339+
end)
340+
end
341+
301342
@doc """
302343
Returns the length of an array at the given JSON Pointer path, or `nil` if
303344
the path does not exist or does not point to an array.

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Torque.MixProject do
22
use Mix.Project
33

4-
@version "0.1.8"
4+
@version "0.1.9"
55
@source_url "https://github.com/lpgauth/torque"
66

77
def project do

0 commit comments

Comments
 (0)