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', => '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
Parse a field from a raw header line:
Mail::Field.parse("field-name: field data")
=> #<Mail::Field …>
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 |