recursive structure used internally to represent message trees as described by reply-to: and references: headers.
the 'id' field is the same as the message id. but the message might be empty, in the case that we represent a message that was referenced by another message (as an ancestor) but never received.
# File lib/sup/thread.rb, line 160 def initialize id raise "non-String #{id.inspect}" unless id.is_a? String @id = id @message, @parent, @thread = nil, nil, nil @children = [] end
# File lib/sup/thread.rb, line 182 def == o; Container === o && id == o.id; end
# File lib/sup/thread.rb, line 208 def date; find_attr :date; end
# File lib/sup/thread.rb, line 174 def descendant_of? o if o == self true else @parent && @parent.descendant_of?(o) end end
# File lib/sup/thread.rb, line 219 def dump_recursive f=$stdout, indent=0, root=true, parent=nil raise "inconsistency" unless parent.nil? || parent.children.include?(self) unless root f.print " " * indent f.print "+->" end line = "[#{thread.nil? ? ' ' : '*'}] " + #"[#{useful? ? 'U' : ' '}] " + if @message message.subj ##{@message.refs.inspect} / #{@message.replytos.inspect}" else "<no message>" end f.puts "#{id} #{line}"#[0 .. (105 - indent)] indent += 3 @children.each { |c| c.dump_recursive f, indent, false, self } end
# File lib/sup/thread.rb, line 167 def each_with_stuff parent=nil yield self, 0, parent @children.each do |c| c.each_with_stuff(self) { |cc, d, par| yield cc, d + 1, par } end end
# File lib/sup/thread.rb, line 184 def empty?; @message.nil?; end
# File lib/sup/thread.rb, line 200 def find_attr attr if empty? @children.argfind { |c| c.find_attr attr } else @message.send attr end end
skip over any containers which are empty and have only one child. we use this make the threaded display a little nicer, and only stick in the “missing message” line when it's graphically necessary, i.e. when the missing message has more than one descendent.
# File lib/sup/thread.rb, line 192 def first_useful_descendant if empty? && @children.size == 1 @children.first.first_useful_descendant else self end end
# File lib/sup/thread.rb, line 210 def is_reply?; subj && Message.subj_is_reply?(subj); end
# File lib/sup/thread.rb, line 186 def root; root? ? self : @parent.root; end
# File lib/sup/thread.rb, line 185 def root?; @parent.nil?; end
# File lib/sup/thread.rb, line 207 def subj; find_attr :subj; end
# File lib/sup/thread.rb, line 212 def to_s [ "<#{id}", (@parent.nil? ? nil : "parent=#{@parent.id}"), (@children.empty? ? nil : "children=#{@children.map { |c| c.id }.inspect}"), ].compact.join(" ") + ">" end