Module: Sourcerer::Util::ListAmend

Defined in:
lib/sourcerer/util/list_amend.rb

Overview

Merge a user-supplied list into a default list using +/- amendment tokens.

Not required internally; callers must require this file explicitly.

Class Method Summary collapse

Class Method Details

.apply(default_list, custom_list, normalize: nil) ⇒ Array<String>

Apply a custom list on top of a default list.

Behavior:

- +nil+ / empty custom ⇒ return stringified +default_list+
- custom with no +/- tokens ⇒ fixed-list mode: return stringified custom
- custom with any +/- token ⇒ amendment mode:
    -slug  removes slug from working set (or no-op)
    +slug  adds slug if not already present
    bare   treated as +slug

Parameters:

  • default_list (Array<#to_s>)

    the baseline list of items

  • custom_list (nil, String, Array<#to_s>)

    the user-supplied overrides

  • normalize (nil, #call) (defaults to: nil)

    optional normalizer for deduplication comparisons (e.g. :downcase.to_proc)

Returns:

  • (Array<String>)


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/sourcerer/util/list_amend.rb', line 23

def self.apply default_list, custom_list, normalize: nil
  tokens = parse_tokens(custom_list)
  return default_list.map(&:to_s) if tokens.empty?

  amendment_mode = tokens.any? { |t| t.start_with?('+', '-') }
  return tokens.map(&:to_s) unless amendment_mode

  working = default_list.map(&:to_s)
  norm    = normalize || ->(s) { s }

  # Apply removals first, then additions in token order.
  tokens.each do |token|
    if token.start_with?('-')
      slug = token[1..]
      working.reject! { |item| norm.call(item) == norm.call(slug) }
    else
      slug = token.start_with?('+') ? token[1..] : token
      working << slug unless working.any? { |item| norm.call(item) == norm.call(slug) }
    end
  end

  working
end