class Redwood::Container

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.

Attributes

children[RW]
id[RW]
message[RW]
parent[RW]
thread[RW]

Public Class Methods

new(id) click to toggle source
# 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

Public Instance Methods

==(o;) click to toggle source
# File lib/sup/thread.rb, line 182
def == o; Container === o && id == o.id; end
date() click to toggle source
# File lib/sup/thread.rb, line 208
def date; find_attr :date; end
descendant_of?(o) click to toggle source
# File lib/sup/thread.rb, line 174
def descendant_of? o
  if o == self
    true
  else
    @parent && @parent.descendant_of?(o)
  end
end
dump_recursive(f=$stdout, indent=0, root=true, parent=nil) click to toggle source
# 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
each_with_stuff(parent=nil) { |self, 0, parent| ... } click to toggle source
# 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
empty?() click to toggle source
# File lib/sup/thread.rb, line 184
def empty?; @message.nil?; end
find_attr(attr) click to toggle source
# 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
first_useful_descendant() click to toggle source

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
is_reply?() click to toggle source
# File lib/sup/thread.rb, line 210
def is_reply?; subj && Message.subj_is_reply?(subj); end
root() click to toggle source
# File lib/sup/thread.rb, line 186
def root; root? ? self : @parent.root; end
root?() click to toggle source
# File lib/sup/thread.rb, line 185
def root?; @parent.nil?; end
subj() click to toggle source
# File lib/sup/thread.rb, line 207
def subj; find_attr :subj; end
to_s() click to toggle source
# 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