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_pathin the mailbox namedvar_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 |