Last active
December 26, 2019 15:04
-
-
Save ykon/e24fa91654efee17cca428dc05573d40 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# typed: true | |
# Ruby 2.6 (Function Composition, filter) | |
require 'sorbet-runtime' | |
class MailHeader | |
extend T::Sig | |
TEST_FILE_PATH = '/tmp/__mail_header_test_file__' | |
sig {void} | |
def self.make_test_file() | |
if FileTest.file?(TEST_FILE_PATH) | |
return | |
end | |
text = <<-EOS | |
Received: from mail2.example.jp (mail2 [127.0.0.1]) | |
by mail2.example.jp (Postfix) with SMTP id 8EA8999C0C2; | |
Tue, 23 Aug 2011 11:06:24 +0900 (JST) | |
Received: from mail1.example.jp (unknown [172.16.0.1]) | |
by mail2.example.jp (Postfix) with SMTP; | |
Tue, 23 Aug 2011 11:06:24 +0900 (JST) | |
Received: from ([192.168.1.1]) (envelope sender: <[email protected]>) | |
by mail1.example.jp with Active!Hunter esmtp server; | |
Tue, 23 Aug 2011 11:06:18 +0900 | |
From: Taro Yamada <[email protected]> | |
To: Jiro Tanaka <[email protected]>, Saburo Watanabe <[email protected]>, | |
Hanako Takahashi <[email protected]> | |
Date: Mon, 22 Aug 2011 19:06:14 -0700 | |
Subject: Hello | |
Message-ID: <CA79398B.2383D%[email protected]> | |
In-Reply-To: <[email protected]> | |
Content-Type: text/plain | |
MIME-Version: 1.0 | |
Empty: | |
Hi Taro | |
This is a test message. | |
END | |
EOS | |
File.write(TEST_FILE_PATH, text.gsub(/\n/, "\r\n")) | |
end | |
sig {params(text: String).returns(T::Array[String])} | |
def self.split_header_body(text) | |
res = text.split("\r\n\r\n", 2) | |
if res.length != 2 then raise ArgumentError end | |
res | |
end | |
sig {params(header: String).returns(String)} | |
def self.unfold_header(header) | |
header.gsub(/\r\n[ \t]+/, ' ') | |
end | |
sig {params(line: String).returns(T.nilable(T::Array[T.nilable(String)]))} | |
def self.split_field(line) | |
m = line.match(/(\S+): *(.+)?/) | |
m.nil? ? nil : [m[1], m[2].nil? ? nil : T.must(m[2]).rstrip] | |
end | |
sig {params(header: String).returns(T::Hash[String, T::Array[T.nilable(String)]])} | |
def self.parse_header(header) | |
if header.empty? then raise ArgumentError end | |
header.lines.map(&:chomp) | |
.map(&method(:split_field)) | |
.filter{|a| !a.nil?} | |
.group_by{|fn,_| fn} | |
.map{|k,v| [k.downcase, v.map{|h| h[1]}]}.to_h | |
end | |
sig {void} | |
def self.main() | |
make_test_file() | |
text = File.read(TEST_FILE_PATH) | |
header, _ = split_header_body(text) | |
puts (method(:unfold_header) >> method(:parse_header)).call(T.must(header)) | |
end | |
end | |
if __FILE__ == $PROGRAM_NAME | |
MailHeader.main() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment