Class: Ast::Merge::ProviderRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/ast/merge/provider_registry.rb,
sig/ast/merge.rbs

Overview

Registers providers and dispatches portable merge operations. rubocop:disable Metrics/ClassLength -- registry selection and dispatch remain one cohesive boundary

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeProviderRegistry

Returns a new instance of ProviderRegistry.



16
17
18
19
# File 'lib/ast/merge/provider_registry.rb', line 16

def initialize
  @mutex = Mutex.new
  @registrations = {}
end

Class Method Details

.defaultProviderRegistry

Returns:



11
12
13
# File 'lib/ast/merge/provider_registry.rb', line 11

def default
  @default_mutex.synchronize { @default ||= new }
end

Instance Method Details

#clearProviderRegistry

Returns:



73
74
75
76
# File 'lib/ast/merge/provider_registry.rb', line 73

def clear
  @mutex.synchronize { @registrations.clear }
  self
end

#dispatch(operation, request) ⇒ provider_result

rubocop:enable Metrics/ParameterLists

Parameters:

  • operation (provider_operation)
  • request (provider_request)

Returns:

  • (provider_result)


61
62
63
64
65
66
67
68
69
70
71
# File 'lib/ast/merge/provider_registry.rb', line 61

def dispatch(operation, request)
  operation = ProviderContract.normalize_operation(operation)
  normalized_request = validate_request(operation, request)
  return normalized_request if invalid_request_result?(normalized_request)

  provider = resolve_for_request(operation, normalized_request)
  return unsupported_result(operation, normalized_request) unless provider

  result = provider.public_send(operation, normalized_request)
  ProviderContract.validate_result!(operation, result)
end

#fetch(provider_id) ⇒ Hash[Symbol, untyped]?

Parameters:

  • provider_id (String)

Returns:

  • (Hash[Symbol, untyped], nil)


35
36
37
# File 'lib/ast/merge/provider_registry.rb', line 35

def fetch(provider_id)
  @mutex.synchronize { @registrations[provider_id.to_s] }
end

#providersArray[Hash[Symbol, untyped]]

Returns:

  • (Array[Hash[Symbol, untyped]])


39
40
41
42
43
# File 'lib/ast/merge/provider_registry.rb', line 39

def providers
  @mutex.synchronize do
    @registrations.values.sort_by { |registration| registration.fetch(:provider_id) }
  end
end

#register(provider, replace: false) ⇒ _MergeProvider

Parameters:

Returns:



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/ast/merge/provider_registry.rb', line 21

def register(provider, replace: false)
  registration = ProviderContract.validate_provider!(provider)
  provider_id = registration.fetch(:provider_id)

  @mutex.synchronize do
    if @registrations.key?(provider_id) && !replace
      raise ProviderContract::DuplicateProviderError, "Provider already registered: #{provider_id}"
    end

    @registrations[provider_id] = registration.merge(provider: provider).freeze
  end
  provider
end

#resolve(provider_id: nil, family: nil, dialect: nil, backend: nil, profile_id: nil, operation: nil) ⇒ _MergeProvider?

rubocop:disable Metrics/ParameterLists -- selectors mirror the portable request envelope

Parameters:

  • provider_id: (String, nil) (defaults to: nil)
  • family: (String, nil) (defaults to: nil)
  • dialect: (String, nil) (defaults to: nil)
  • backend: (String, nil) (defaults to: nil)
  • profile_id: (String, nil) (defaults to: nil)
  • operation: (provider_operation, nil) (defaults to: nil)

Returns:



46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ast/merge/provider_registry.rb', line 46

def resolve(provider_id: nil, family: nil, dialect: nil, backend: nil, profile_id: nil, operation: nil)
  selectors = normalize_selectors(
    family: family,
    dialect: dialect,
    backend: backend,
    profile_id: profile_id,
    operation: operation
  )
  return resolve_by_id(provider_id, selectors) if provider_id

  candidates = providers.select { |registration| matches?(registration, selectors) }
  candidates.min_by { |registration| preference(registration, selectors) }&.fetch(:provider)
end