Class: AceMQ::AMQP::TOMLCodec
- Inherits:
-
Object
- Object
- AceMQ::AMQP::TOMLCodec
- Defined in:
- lib/acemq/amqp/codec/toml.rb,
lib/acemq/amqp/codec/toml/reader.rb,
lib/acemq/amqp/codec/toml/writer.rb
Overview
Reads and writes TOML.
The same audience as YAMLCodec — a message a person reads and edits —
with the ambiguity removed. TOML has one way to write a string, no
significant indentation, and no Norway problem: in YAML country: NO is
the boolean false, while here an unquoted NO is a parse error rather
than a country that quietly became a boolean. Where a human edits the
message and a machine acts on it, that matters more than terseness.
A poor choice for high volume: it is text, it is larger than JSON, and it parses more slowly than any of the binary formats.
The shape of the data has to suit it
TOML is a table format, so a message body is an object at the top level. A bare list or a bare number is not a TOML document, and this says so rather than writing something no parser will read back. Deep nesting reads poorly too; where the payload is a tree rather than a table, JSON is the honest answer.
Why the parser is written here
There is no TOML parser in Ruby's standard library and this gem declares
no runtime dependencies, so the reader and writer below are the codec. The
bar they are held to is the one that matters: the bytes Jackson's
TomlMapper writes in the Java library and the bytes BurntSushi's encoder
writes in the Go one. Those two do not agree on everything — Jackson
quotes strings with ' and Go with " — so a reader that handled only
one of them would be a codec that could read half the estate.
Defined Under Namespace
Constant Summary collapse
- CONTENT_TYPE =
What this codec writes: the type the TOML specification registered, and what Java, Go and .NET write.
"application/toml"- ALSO_READS =
Predates the registration and is still what a lot of tooling writes.
["text/toml"].freeze
Instance Method Summary collapse
-
#can_decode?(content_type) ⇒ Boolean
Accepts
application/toml,text/tomland any +...+toml+ media type. - #content_type ⇒ Object
- #decode(body) ⇒ Hash
- #encode(payload) ⇒ String
Instance Method Details
#can_decode?(content_type) ⇒ Boolean
Accepts application/toml, text/toml and any +...+toml+ media type.
Never a message whose sender set no content type: the same reasoning as YAMLCodec. A sender that said nothing is almost always sending JSON, and answering would be right about the value and wrong about the format.
91 92 93 94 95 96 |
# File 'lib/acemq/amqp/codec/toml.rb', line 91 def can_decode?(content_type) lower = content_type.to_s.downcase return false if lower.empty? lower.start_with?(CONTENT_TYPE, *ALSO_READS) || lower.include?("+toml") end |
#content_type ⇒ Object
60 |
# File 'lib/acemq/amqp/codec/toml.rb', line 60 def content_type = CONTENT_TYPE |
#decode(body) ⇒ Hash
80 81 82 83 84 |
# File 'lib/acemq/amqp/codec/toml.rb', line 80 def decode(body) Reader.new(body.to_s).parse rescue Reader::Invalid => e raise DecodeError, "this message is not TOML: #{e.}" end |
#encode(payload) ⇒ String
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/acemq/amqp/codec/toml.rb', line 66 def encode(payload) unless payload.is_a?(Hash) raise EncodeError, "cannot encode a #{payload.class} as TOML: a TOML document is a table, so " \ "the top level has to be a Hash. A list, a string or a number has no TOML " \ "representation — wrap it in a hash with a named key, or use JSON." end Writer.new.write(payload) end |