File: plugin_list.rb

package info (click to toggle)
ruby-aws-sdk-core 3.212.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,232 kB
  • sloc: ruby: 17,533; makefile: 4
file content (146 lines) | stat: -rw-r--r-- 3,467 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# frozen_string_literal: true

require 'set'
require 'thread'

module Seahorse
  module Client
    class PluginList

      include Enumerable

      # @param [Array, Set] plugins
      # @option options [Mutex] :mutex
      def initialize(plugins = [], options = {})
        @mutex = options[:mutex] || Mutex.new
        @plugins = Set.new
        if plugins.is_a?(PluginList)
          plugins.send(:each_plugin) { |plugin| _add(plugin) }
        else
          plugins.each { |plugin| _add(plugin) }
        end
      end

      # Adds and returns the `plugin`.
      # @param [Plugin] plugin
      # @return [void]
      def add(plugin)
        @mutex.synchronize do
          _add(plugin)
        end
        nil
      end

      # Removes and returns the `plugin`.
      # @param [Plugin] plugin
      # @return [void]
      def remove(plugin)
        @mutex.synchronize do
          @plugins.delete(PluginWrapper.new(plugin))
        end
        nil
      end

      # Replaces the existing list of plugins.
      # @param [Array<Plugin>] plugins
      # @return [void]
      def set(plugins)
        @mutex.synchronize do
          @plugins.clear
          plugins.each do |plugin|
            _add(plugin)
          end
        end
        nil
      end

      # Enumerates the plugins.
      # @return [Enumerator]
      def each(&block)
        each_plugin do |plugin_wrapper|
          yield(plugin_wrapper.plugin)
        end
      end

      private

      # Not safe to call outside the mutex.
      def _add(plugin)
        @plugins << PluginWrapper.new(plugin)
      end

      # Yield each PluginDetail behind the mutex
      def each_plugin(&block)
        @mutex.synchronize do
          @plugins.each(&block)
        end
      end

      # A utility class that computes the canonical name for a plugin
      # and defers requiring the plugin until the plugin class is
      # required.
      # @api private
      class PluginWrapper

        # @param [String, Symbol, Module, Class] plugin
        def initialize(plugin)
          case plugin
          when Module
            @canonical_name = plugin.name || plugin.object_id
            @plugin = plugin
          when Symbol, String
            words = plugin.to_s.split('.')
            @canonical_name = words.pop
            @gem_name = words.empty? ? nil : words.join('.')
            @plugin = nil
          else
            @canonical_name = plugin.object_id
            @plugin = plugin
          end
        end

        # @return [String]
        attr_reader :canonical_name

        # @return [Class<Plugin>]
        def plugin
          @plugin ||= require_plugin
        end

        # Returns the given plugin if it is already a PluginWrapper.
        def self.new(plugin)
          if plugin.is_a?(self)
            plugin
          else
            super
          end
        end

        # @return [Boolean]
        # @api private
        def eql? other
          canonical_name == other.canonical_name
        end

        # @return [String]
        # @api private
        def hash
          canonical_name.hash
        end

        private

        # @return [Class<Plugin>]
        def require_plugin
          require(@gem_name) if @gem_name
          plugin_class = Kernel
          @canonical_name.split('::').each do |const_name|
            plugin_class = plugin_class.const_get(const_name)
          end
          plugin_class
        end

      end
    end
  end
end