diff options
Diffstat (limited to 'lib/rbot')
-rw-r--r-- | lib/rbot/core/utils/filters.rb | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/rbot/core/utils/filters.rb b/lib/rbot/core/utils/filters.rb new file mode 100644 index 00000000..5744b732 --- /dev/null +++ b/lib/rbot/core/utils/filters.rb @@ -0,0 +1,80 @@ +#-- vim:sw=2:et +#++ +# +# :title: Stream filters +# +# Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com> +# Copyright:: (C) 2008 Giuseppe Bilotta +# License:: GPL v2 +# +# This file collects methods to handle 'stream filters', a generic mechanism +# to transform text+attributes into other text+attributes + +module ::Irc + class Bot + + # The DataStream class. A DataStream is just a Hash. The :text key has + # a special meaning because it's the value that will be used when + # converting to String + class DataStream < Hash + + def initialize(hsh={}) + self.replace(hsh) + end + + # Returns the :text key + def to_s + return self[:text] + end + end + + # The DataFilter class. A DataFilter is a wrapper around a block + # that can be run on a DataStream to process it. The block is supposed to + # return another DataStream object + class DataFilter + def initialize(&block) + raise "No block provided" unless block_given? + @block = block + end + + def call(stream) + @block.call(stream) + end + alias :run :call + alias :filter :call + end + + # This method processes the DataStream _stream_ with the filters _name_. + # _name_ can be either a single Symbol (filter name), or an Array of + # Symbols, in which case the output of each filter will be used as input + # for the next + # + def filter(name, stream={}) + @filters ||= {} + names = (Symbol === name ? [name] : name.dup) + ds = (DataStream === stream ? stream : DataStream.new(stream)) + return ds if names.empty? + # check if filters exist + missing = names - @filters.keys + raise "Missing filters: #{missing.join(', ')}" unless missing.empty? + fs = @filters.values_at(*names) + fs.inject(ds) { |mid, f| mid = f.call(mid) } + end + + # This method is used to register a new filter + def register_filter(name, &block) + raise "No block provided" unless block_given? + @filters ||= {} + @filters[name.to_sym] = DataFilter.new &block + end + + # This method clears the filter list and installs the identity filter + def clear_filters + @filters ||= {} + @filters.clear + register_filter(:identity) { |stream| stream } + end + end +end + + |