Class: Mailmate::VarResolver Private
- Inherits:
-
Object
- Object
- Mailmate::VarResolver
- Defined in:
- lib/mailmate/var_resolver.rb
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Defined Under Namespace
Classes: CycleError, UnsupportedVar
Instance Method Summary collapse
-
#initialize(graph) ⇒ VarResolver
constructor
private
A new instance of VarResolver.
-
#resolve(var_name, attr_path) ⇒ Object
private
Returns an Array<String|AddressValue|…> of values seen for ‘attr_path` in the mailbox named `var_name`.
Constructor Details
#initialize(graph) ⇒ VarResolver
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of VarResolver.
28 29 30 31 32 33 |
# File 'lib/mailmate/var_resolver.rb', line 28 def initialize(graph) @graph = graph @source_resolver = SourceResolver.new(graph) @cache = {} @visiting = [] end |
Instance Method Details
#resolve(var_name, attr_path) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns an Array<String|AddressValue|…> of values seen for ‘attr_path` in the mailbox named `var_name`. Empty array if no matches.
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 |
# File 'lib/mailmate/var_resolver.rb', line 37 def resolve(var_name, attr_path) key = [var_name, attr_path] return @cache[key] if @cache.key?(key) raise CycleError, "var-resolution cycle: #{(@visiting + [var_name]).join(" → ")}" \ if @visiting.include?(var_name) @visiting << var_name begin # 1. Resolve the variable's mailbox to dirs + smart-filter chain. uuid = MailboxGraph::SPECIAL_UUIDS.include?(var_name) ? var_name : @graph.by_name[var_name] raise UnsupportedVar, "Unknown mailbox referenced: $#{var_name}" unless uuid res = @source_resolver.resolve(uuid) dirs = res[:dirs] filter_str = compose_filter(res[:filters]) # 2. Build a child evaluator if there's an inner filter, with the # *same* var resolver so nested $vars resolve. inner_eval = filter_str ? Evaluator.new(Mailmate.compile_filter(filter_str), var_resolver: self) : nil # 3. Walk dirs, collect attr_path values from matching messages. values = [] dirs.each do |dir| Dir.each_child(dir) do |fname| next unless fname.end_with?(".eml") path = "#{dir}/#{fname}" eml_id = fname.sub(".eml", "").to_i begin # Header-only parse: most $var attrs are headers, and a full # Mail.read on each Sent message would be slow. mail = Mail.new(read_header_block(path)) rescue StandardError next end msg = Message.new(mail, eml_id, path) next if inner_eval && !inner_eval.matches?(msg) v = Attributes.resolve(msg, attr_path) Array(v).each { |x| values << x.to_s if x } end end @cache[key] = values ensure @visiting.pop end end |