Class: Mail::Field
Overview
Provides a single class to call to create a new structured or unstructured field. Works out per RFC what field of field it is being given and returns the correct field of class back on new.
Per RFC 2822
2.2. Header Fields
Header fields are lines composed of a field name, followed by a colon
(":"), followed by a field body, and terminated by CRLF. A field
name MUST be composed of printable US-ASCII characters (i.e.,
characters that have values between 33 and 126, inclusive), except
colon. A field body may be composed of any US-ASCII characters,
except for CR and LF. However, a field body may contain CRLF when
used in header "folding" and "unfolding" as described in section
2.2.3. All field bodies MUST conform to the syntax described in
sections 3 and 4 of this standard.
Defined Under Namespace
Classes: FieldError, IncompleteParseError, NilParseError, ParseError, SyntaxError
Constant Summary collapse
- STRUCTURED_FIELDS =
%w[ bcc cc content-description content-disposition content-id content-location content-transfer-encoding content-type date from in-reply-to keywords message-id mime-version received references reply-to resent-bcc resent-cc resent-date resent-from resent-message-id resent-sender resent-to return-path sender to ]
- KNOWN_FIELDS =
STRUCTURED_FIELDS + ['comments', 'subject']
- FIELDS_MAP =
{ "to" => "ToField", "cc" => "CcField", "bcc" => "BccField", "message-id" => "MessageIdField", "in-reply-to" => "InReplyToField", "references" => "ReferencesField", "subject" => "SubjectField", "comments" => "CommentsField", "keywords" => "KeywordsField", "date" => "DateField", "from" => "FromField", "sender" => "SenderField", "reply-to" => "ReplyToField", "resent-date" => "ResentDateField", "resent-from" => "ResentFromField", "resent-sender" => "ResentSenderField", "resent-to" => "ResentToField", "resent-cc" => "ResentCcField", "resent-bcc" => "ResentBccField", "resent-message-id" => "ResentMessageIdField", "return-path" => "ReturnPathField", "received" => "ReceivedField", "mime-version" => "MimeVersionField", "content-transfer-encoding" => "ContentTransferEncodingField", "content-description" => "ContentDescriptionField", "content-disposition" => "ContentDispositionField", "content-type" => "ContentTypeField", "content-id" => "ContentIdField", "content-location" => "ContentLocationField", }
- FIELD_NAME_MAP =
{ "to" => "To", "cc" => "Cc", "bcc" => "Bcc", "message-id" => "Message-ID", "in-reply-to" => "In-Reply-To", "references" => "References", "subject" => "Subject", "comments" => "Comments", "keywords" => "Keywords", "date" => "Date", "from" => "From", "sender" => "Sender", "reply-to" => "Reply-To", "resent-date" => "Resent-Date", "resent-from" => "Resent-From", "resent-sender" => "Resent-Sender", "resent-to" => "Resent-To", "resent-cc" => "Resent-Cc", "resent-bcc" => "Resent-Bcc", "resent-message-id" => "Resent-Message-ID", "return-path" => "Return-Path", "received" => "Received", "mime-version" => "MIME-Version", "content-transfer-encoding" => "Content-Transfer-Encoding", "content-description" => "Content-Description", "content-disposition" => "Content-Disposition", "content-type" => "Content-Type", "content-id" => "Content-ID", "content-location" => "Content-Location", }
- FIELD_ORDER_LOOKUP =
Instance Attribute Summary collapse
-
#unparsed_value ⇒ Object
readonly
Returns the value of attribute unparsed_value.
Class Method Summary collapse
-
.field_class_for(name) ⇒ Object
:nodoc:.
-
.parse(field, charset = 'utf-8') ⇒ Object
Parse a field from a raw header line:.
-
.split(raw_field) ⇒ Object
:nodoc:.
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #==(other) ⇒ Object
- #field ⇒ Object
- #field=(field) ⇒ Object
- #field_order_id ⇒ Object
-
#initialize(name, value = nil, charset = 'utf-8') ⇒ Field
constructor
Create a field by name and optional value:.
- #inspect ⇒ Object
- #method_missing(name, *args, &block) ⇒ Object
- #name ⇒ Object
- #respond_to_missing?(method_name, include_private) ⇒ Boolean
- #responsible_for?(field_name) ⇒ Boolean
- #same(other) ⇒ Object
- #to_s ⇒ Object
- #value ⇒ Object
- #value=(val) ⇒ Object
Constructor Details
#initialize(name, value = nil, charset = 'utf-8') ⇒ Field
Create a field by name and optional value:
Mail::Field.new("field-name", "value")
# => #<Mail::Field …>
Values that aren’t strings or arrays are coerced to Strings with ‘#to_s`.
Mail::Field.new("field-name", 1234)
# => #<Mail::Field …>
Mail::Field.new('content-type', ['text', 'plain', {:charset => 'UTF-8'}])
# => #<Mail::Field …>
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/mail/field.rb', line 195 def initialize(name, value = nil, charset = 'utf-8') case when name.index(Constants::COLON) raise ArgumentError, 'Passing an unparsed header field to Mail::Field.new is not supported in Mail 2.8.0+. Use Mail::Field.parse instead.' when Utilities.blank?(value) @name = name @unparsed_value = nil @charset = charset else @name = name @unparsed_value = value @charset = charset end klass = self.class.field_class_for(@name) @name = klass ? klass::NAME : @name end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
262 263 264 |
# File 'lib/mail/field.rb', line 262 def method_missing(name, *args, &block) field.send(name, *args, &block) end |
Instance Attribute Details
#unparsed_value ⇒ Object (readonly)
Returns the value of attribute unparsed_value.
181 182 183 |
# File 'lib/mail/field.rb', line 181 def unparsed_value @unparsed_value end |
Class Method Details
.field_class_for(name) ⇒ Object
:nodoc:
175 176 177 178 |
# File 'lib/mail/field.rb', line 175 def field_class_for(name) #:nodoc: class_name = FIELDS_MAP[name.to_s.downcase] Mail.const_get(class_name) if class_name end |
.parse(field, charset = 'utf-8') ⇒ Object
150 151 152 153 154 155 |
# File 'lib/mail/field.rb', line 150 def parse(field, charset = 'utf-8') name, value = split(field) if name && value new name, value, charset end end |
.split(raw_field) ⇒ Object
:nodoc:
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/mail/field.rb', line 157 def split(raw_field) #:nodoc: if raw_field.index(Constants::COLON) name, value = raw_field.split(Constants::COLON, 2) name.rstrip! if /\A#{Constants::FIELD_NAME}\z/.match?(name) [ name.rstrip, value.strip ] else Kernel.warn "WARNING: Ignoring unparsable header #{raw_field.inspect}: invalid header name syntax: #{name.inspect}" nil end else raw_field.strip end rescue => error warn "WARNING: Ignoring unparsable header #{raw_field.inspect}: #{error.class}: #{error.}" nil end |
Instance Method Details
#<=>(other) ⇒ Object
254 255 256 |
# File 'lib/mail/field.rb', line 254 def <=>(other) field_order_id <=> other.field_order_id end |
#==(other) ⇒ Object
246 247 248 |
# File 'lib/mail/field.rb', line 246 def ==(other) same(other) && Utilities.match_to_s(other.value, value) end |
#field ⇒ Object
216 217 218 |
# File 'lib/mail/field.rb', line 216 def field @field ||= create_field(@name, @unparsed_value, @charset) end |
#field=(field) ⇒ Object
212 213 214 |
# File 'lib/mail/field.rb', line 212 def field=(field) @field = field end |
#field_order_id ⇒ Object
258 259 260 |
# File 'lib/mail/field.rb', line 258 def field_order_id @field_order_id ||= FIELD_ORDER_LOOKUP.fetch(self.name.to_s.downcase, 100) end |
#inspect ⇒ Object
236 237 238 239 240 |
# File 'lib/mail/field.rb', line 236 def inspect "#<#{self.class.name} 0x#{(object_id * 2).to_s(16)} #{instance_variables.map do |ivar| "#{ivar}=#{instance_variable_get(ivar).inspect}" end.join(" ")}>" end |
#name ⇒ Object
220 221 222 |
# File 'lib/mail/field.rb', line 220 def name @name end |
#respond_to_missing?(method_name, include_private) ⇒ Boolean
266 267 268 |
# File 'lib/mail/field.rb', line 266 def respond_to_missing?(method_name, include_private) field.respond_to?(method_name, include_private) || super end |
#responsible_for?(field_name) ⇒ Boolean
250 251 252 |
# File 'lib/mail/field.rb', line 250 def responsible_for?(field_name) name.to_s.casecmp(field_name.to_s) == 0 end |
#same(other) ⇒ Object
242 243 244 |
# File 'lib/mail/field.rb', line 242 def same(other) other.kind_of?(self.class) && Utilities.match_to_s(other.name, name) end |
#to_s ⇒ Object
232 233 234 |
# File 'lib/mail/field.rb', line 232 def to_s field.to_s end |
#value ⇒ Object
224 225 226 |
# File 'lib/mail/field.rb', line 224 def value field.value end |
#value=(val) ⇒ Object
228 229 230 |
# File 'lib/mail/field.rb', line 228 def value=(val) @field = create_field(name, val, @charset) end |