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
|
# frozen_string_literal: true
require 'delegate'
module Mail
class PartsList < DelegateClass(Array)
attr_reader :parts
def initialize(*args)
@parts = Array.new(*args)
super @parts
end
# The #encode_with and #to_yaml methods are just implemented
# for the sake of backward compatibility ; the delegator does
# not correctly delegate these calls to the delegated object
def encode_with(coder) # :nodoc:
coder.represent_object(nil, @parts)
end
def to_yaml(options = {}) # :nodoc:
@parts.to_yaml(options)
end
def attachments
Mail::AttachmentsList.new(@parts)
end
def collect
if block_given?
ary = PartsList.new
each { |o| ary << yield(o) }
ary
else
to_a
end
end
alias_method :map, :collect
def map!
raise NoMethodError, "#map! is not defined, please call #collect and create a new PartsList"
end
def collect!
raise NoMethodError, "#collect! is not defined, please call #collect and create a new PartsList"
end
def sort
self.class.new(@parts.sort)
end
def sort!(order)
# stable sort should be used to maintain the relative order as the parts are added
i = 0;
sorted = @parts.sort_by do |a|
# OK, 10000 is arbitrary... if anyone actually wants to explicitly sort 10000 parts of a
# single email message... please show me a use case and I'll put more work into this method,
# in the meantime, it works :)
[get_order_value(a, order), i += 1]
end
@parts.clear
sorted.each { |p| @parts << p }
end
private
def get_order_value(part, order)
if part.respond_to?(:content_type) && !part[:content_type].nil?
order.index(part[:content_type].string.downcase) || 10000
else
10000
end
end
end
end
|