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 =
FIELDS_MAP.inject({}) do |map, (field, field_klass)| map.update(field => field_klass::NAME) end
- 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 …>
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/mail/field.rb', line 166 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 @name = FIELD_NAME_MAP[@name.to_s.downcase] || @name end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
232 233 234 |
# File 'lib/mail/field.rb', line 232 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.
152 153 154 |
# File 'lib/mail/field.rb', line 152 def unparsed_value @unparsed_value end |
Class Method Details
.field_class_for(name) ⇒ Object
:nodoc:
147 148 149 |
# File 'lib/mail/field.rb', line 147 def field_class_for(name) #:nodoc: FIELDS_MAP[name.to_s.downcase] end |
.parse(field, charset = 'utf-8') ⇒ Object
Parse a field from a raw header line:
Mail::Field.parse("field-name: field data")
=> #<Mail::Field …>
122 123 124 125 126 127 |
# File 'lib/mail/field.rb', line 122 def parse(field, charset = 'utf-8') name, value = split(field) if name && value new name, value, charset end end |
.split(raw_field) ⇒ Object
:nodoc:
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/mail/field.rb', line 129 def split(raw_field) #:nodoc: if raw_field.index(Constants::COLON) name, value = raw_field.split(Constants::COLON, 2) name.rstrip! if name =~ /\A#{Constants::FIELD_NAME}\z/ [ 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.message}" nil end |
Instance Method Details
#<=>(other) ⇒ Object
224 225 226 |
# File 'lib/mail/field.rb', line 224 def <=>(other) field_order_id <=> other.field_order_id end |
#==(other) ⇒ Object
216 217 218 |
# File 'lib/mail/field.rb', line 216 def ==(other) same(other) && Utilities.match_to_s(other.value, value) end |
#field ⇒ Object
186 187 188 |
# File 'lib/mail/field.rb', line 186 def field @field ||= create_field(@name, @unparsed_value, @charset) end |
#field=(field) ⇒ Object
182 183 184 |
# File 'lib/mail/field.rb', line 182 def field=(field) @field = field end |
#field_order_id ⇒ Object
228 229 230 |
# File 'lib/mail/field.rb', line 228 def field_order_id @field_order_id ||= FIELD_ORDER_LOOKUP.fetch(self.name.to_s.downcase, 100) end |
#inspect ⇒ Object
206 207 208 209 210 |
# File 'lib/mail/field.rb', line 206 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
190 191 192 |
# File 'lib/mail/field.rb', line 190 def name @name end |
#respond_to_missing?(method_name, include_private) ⇒ Boolean
236 237 238 |
# File 'lib/mail/field.rb', line 236 def respond_to_missing?(method_name, include_private) field.respond_to?(method_name, include_private) || super end |
#responsible_for?(field_name) ⇒ Boolean
220 221 222 |
# File 'lib/mail/field.rb', line 220 def responsible_for?(field_name) name.to_s.casecmp(field_name.to_s) == 0 end |
#same(other) ⇒ Object
212 213 214 |
# File 'lib/mail/field.rb', line 212 def same(other) other.kind_of?(self.class) && Utilities.match_to_s(other.name, name) end |
#to_s ⇒ Object
202 203 204 |
# File 'lib/mail/field.rb', line 202 def to_s field.to_s end |
#value ⇒ Object
194 195 196 |
# File 'lib/mail/field.rb', line 194 def value field.value end |
#value=(val) ⇒ Object
198 199 200 |
# File 'lib/mail/field.rb', line 198 def value=(val) @field = create_field(name, val, @charset) end |