Class: Ace::Support::Items::Molecules::ShortcutResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/support/items/molecules/shortcut_resolver.rb

Overview

Resolves shortcut references to item ScanResult objects.

Shortcuts are the last N characters of an item ID. For ideas (6-char IDs): “8ppq7w” => shortcut “q7w” For tasks (9-char formatted IDs): “8pp.t.q7w” => shortcut “q7w” Full IDs are also accepted directly.

Warns (via callback or STDERR) when multiple matches are found.

Instance Method Summary collapse

Constructor Details

#initialize(scan_results, full_id_length: 6) ⇒ ShortcutResolver

Returns a new instance of ShortcutResolver.

Parameters:

  • scan_results (Array<ScanResult>)

    Scan results to resolve against

  • full_id_length (Integer) (defaults to: 6)

    Length of a full ID (6 for raw b36ts, 9 for type-marked)



18
19
20
21
# File 'lib/ace/support/items/molecules/shortcut_resolver.rb', line 18

def initialize(scan_results, full_id_length: 6)
  @scan_results = scan_results
  @full_id_length = full_id_length
end

Instance Method Details

#all_matches(ref) ⇒ Array<ScanResult>

Return all matches for a reference (useful for listing ambiguous matches)

Parameters:

  • ref (String)

    Reference to resolve

Returns:

  • (Array<ScanResult>)

    All matching results



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ace/support/items/molecules/shortcut_resolver.rb', line 72

def all_matches(ref)
  return [] if ref.nil? || ref.empty?

  ref = ref.strip.downcase

  if ref.length == @full_id_length
    @scan_results.select { |r| r.id == ref }
  else
    @scan_results.select { |r| r.id.end_with?(ref) }
  end
end

#ambiguous?(ref) ⇒ Boolean

Check if a reference would be ambiguous

Parameters:

  • ref (String)

    Reference to check

Returns:

  • (Boolean)

    True if multiple matches exist



61
62
63
64
65
66
67
# File 'lib/ace/support/items/molecules/shortcut_resolver.rb', line 61

def ambiguous?(ref)
  return false if ref.nil? || ref.length == @full_id_length

  ref = ref.strip.downcase
  matches = @scan_results.select { |r| r.id.end_with?(ref) }
  matches.size > 1
end

#resolve(ref, on_ambiguity: nil) ⇒ ScanResult?

Resolve a reference to a single ScanResult

Parameters:

  • ref (String)

    Full ID or suffix shortcut

  • on_ambiguity (Proc, nil) (defaults to: nil)

    Called with array of matches on ambiguity

Returns:

  • (ScanResult, nil)

    The resolved result, or nil if not found



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/ace/support/items/molecules/shortcut_resolver.rb', line 27

def resolve(ref, on_ambiguity: nil)
  return nil if ref.nil? || ref.empty?

  ref = ref.strip.downcase

  if ref.length == @full_id_length
    # Full ID match
    exact = @scan_results.find { |r| r.id == ref }
    return exact
  end

  # Suffix match (last N characters)
  matches = @scan_results.select { |r| r.id.end_with?(ref) }

  if matches.empty?
    nil
  elsif matches.size == 1
    matches.first
  else
    # Ambiguity: multiple matches
    if on_ambiguity
      on_ambiguity.call(matches)
    else
      warn "Warning: Ambiguous shortcut '#{ref}' matches #{matches.size} items: " \
           "#{matches.map(&:id).join(", ")}. Using most recent."
    end
    # Return most recent (last by sorted ID = chronologically latest)
    matches.last
  end
end