Skip to content

Instantly share code, notes, and snippets.

@takuma-saito
Created May 3, 2020 15:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takuma-saito/b52da8b9d7b78642bf742fe8a6466105 to your computer and use it in GitHub Desktop.
Save takuma-saito/b52da8b9d7b78642bf742fe8a6466105 to your computer and use it in GitHub Desktop.
Gmail の検索条件を ruby の DSL で扱えるようにした
class Gmail
def initialize(&block)
@block = block
@items = []
end
def run
self.instance_eval(&@block)
@items.join(" ")
end
def cond(condition, &block)
eval_context(block) do |text|
case condition
when :and
"(#{text})"
when :or
"{#{text}}"
when :not
"-#{text}"
else
fail
end
end
end
def eval_context(block)
text = self.class.new(&block).run
compiled_text = yield text
@items.push(compiled_text)
compiled_text
end
def t(text)
@items << text
end
def inbox(&block)
eval_context(block) {|text| "in:(#{text})"}
end
[:subject, :to, :from].each do |method_name|
define_method(method_name) do |&block|
eval_context(block) {|text| "#{method_name}:(#{text})"}
end
end
end
def gmail(&block)
Gmail.new(&block).run
end
puts gmail {
cond(:or) {
cond(:and) {
inbox { t 'anywhere' }
to { t 'guest@example.jp' }
subject {
t '<連絡>'
cond(:or) {
t 'Aさん'
t 'Bさん'
t 'Cさん'
t 'D様'
t 'E様'
t '上様'
t '田中太郎様'
}
}
}
cond(:and) {
from { t 'ok@example.jp' }
cond(:not) {
to { t 'example.org' }
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment