Conversation
Scaffolding for the v2.0 Trustworthy Core release — no behavior change; all 12 v1 tests pass unchanged. - Add .formatter.exs and format lib/, test/, and mix.exs - Add stream_data ~> 1.1 (test/dev only) for upcoming property tests - Raise Elixir requirement from >= 1.9.0 to ~> 1.15 - Bump version to 2.0.0 and rewrite the package description around the structure-preserving, zero-dependency positioning
Introduce the documented predicate engine for removals: depth-first traversal where the predicate receives each key and its already-cleaned value, empty maps left by rejection are preserved, and non-container list elements are untouched. Non-map/non-list input passes through unchanged. Structs are handled explicitly via the structs: option shared by the whole v2 API: :leaf (default) treats them as opaque values, :convert recurses via Map.from_struct/1, :error raises ArgumentError naming the struct module. drop_by_value and drop_by_key are now sugar delegating to reject/3 and gain an optional opts argument. All 9 v1 drop_by_* tests pass unchanged, proving 1.x compatibility of the drop path. New coverage: 11 unit tests and doctests for reject/3 and both sugar functions.
The take-side counterpart to reject/3. Matched entries are kept whole (no recursion into a matched value); unmatched container entries survive only if they have surviving descendants; branches and list elements with no surviving content are pruned. Matches stay at the path where they were found — sibling branches are never merged, fixing the class of silent data loss take_by_key exhibits in 1.x. Shares the structs: option semantics with reject/3 (:leaf default, :convert, :error). Pins the spec's semantics-contract cases in 12 unit tests plus doctests: cross-branch key collisions, list-of-maps, scalars in lists, mixed atom/string keys, struct modes, and pass-through of non-map/non-list input.
take_by_key is now sugar over filter/3: matches stay at the path where
they were found, sibling branches are never merged, and branches without
a match are pruned. This fixes the 1.x behavior of flattening all
matches into a single-level map, which silently lost data whenever the
same key appeared in more than one branch (undefined collision winner).
The three 1.x tests that encoded the flattening behavior are replaced
with structure-preserving expectations, including the spec's headline
case: take_by_key(%{a: %{x: 1}, b: %{x: 2}}, [:x]) returns the map
unchanged. take_by_key also gains the opts argument and forwards the
structs: option.
Both were public but undocumented and are superseded by the documented engine: drop_by/2 by reject/3, take_by/2 by filter/3. The public surface is now exactly reject/3, filter/3, drop_by_value/3, drop_by_key/3, and take_by_key/3. Also replace the placeholder moduledoc with one describing the v2 engine/sugar split and the structure-preservation guarantee.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
v2.0 rewrite per the approved plan (T1–T9):
filter/3/reject/3engines with a sharedstructs: :leaf | :convert | :erroroption (default:leaf);drop_by_value/3,drop_by_key/3,take_by_key/3are now sugar over themtake_by_key/3is structure-preserving — the 1.x flattening (and its silent data loss on duplicate keys) is gonedrop_by/2/take_by/2; Elixir floor raised to~> 1.15Test plan
mix test— 12 doctests, 4 properties, 37 tests, 0 failuresMIX_ENV=test mix coveralls— 100.0%mix format --check-formatted,mix credo --strictcleanmix docsbuilds without warnings