Module: Toon::Primitives
- Defined in:
- lib/toon/primitives.rb
Class Method Summary collapse
-
.encode_key(key) ⇒ Object
Key encoding.
-
.encode_primitive(value, delimiter = COMMA) ⇒ Object
Primitive encoding.
- .encode_string_literal(value, delimiter = COMMA) ⇒ Object
- .escape_string(value) ⇒ Object
-
.format_header(length, key: nil, fields: nil, delimiter: COMMA, length_marker: false) ⇒ Object
Header formatters.
-
.join_encoded_values(values, delimiter = COMMA) ⇒ Object
Value joining.
- .numeric_like?(value) ⇒ Boolean
- .padded_with_whitespace?(value) ⇒ Boolean
- .safe_unquoted?(value, delimiter = COMMA) ⇒ Boolean
- .valid_unquoted_key?(key) ⇒ Boolean
Class Method Details
.encode_key(key) ⇒ Object
Key encoding
60 61 62 63 64 65 66 |
# File 'lib/toon/primitives.rb', line 60 def encode_key(key) if valid_unquoted_key?(key) key else "#{DOUBLE_QUOTE}#{escape_string(key)}#{DOUBLE_QUOTE}" end end |
.encode_primitive(value, delimiter = COMMA) ⇒ Object
Primitive encoding
10 11 12 13 14 15 16 |
# File 'lib/toon/primitives.rb', line 10 def encode_primitive(value, delimiter = COMMA) return NULL_LITERAL if value.nil? return value.to_s if value.is_a?(TrueClass) || value.is_a?(FalseClass) return value.to_s if value.is_a?(Numeric) encode_string_literal(value, delimiter) end |
.encode_string_literal(value, delimiter = COMMA) ⇒ Object
18 19 20 21 22 23 24 |
# File 'lib/toon/primitives.rb', line 18 def encode_string_literal(value, delimiter = COMMA) if safe_unquoted?(value, delimiter) value else "#{DOUBLE_QUOTE}#{escape_string(value)}#{DOUBLE_QUOTE}" end end |
.escape_string(value) ⇒ Object
26 27 28 29 30 31 32 33 |
# File 'lib/toon/primitives.rb', line 26 def escape_string(value) value .gsub(BACKSLASH, "#{BACKSLASH}#{BACKSLASH}") .gsub(DOUBLE_QUOTE, "#{BACKSLASH}#{DOUBLE_QUOTE}") .gsub("\n", "#{BACKSLASH}n") .gsub("\r", "#{BACKSLASH}r") .gsub("\t", "#{BACKSLASH}t") end |
.format_header(length, key: nil, fields: nil, delimiter: COMMA, length_marker: false) ⇒ Object
Header formatters
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/toon/primitives.rb', line 89 def format_header(length, key: nil, fields: nil, delimiter: COMMA, length_marker: false) header = '' header += encode_key(key) if key # Only include delimiter if it's not the default (comma) delimiter_suffix = delimiter != DEFAULT_DELIMITER ? delimiter : '' length_prefix = length_marker ? length_marker : '' header += "[#{length_prefix}#{length}#{delimiter_suffix}]" if fields quoted_fields = fields.map { |f| encode_key(f) } header += "{#{quoted_fields.join(delimiter)}}" end header += COLON header end |
.join_encoded_values(values, delimiter = COMMA) ⇒ Object
Value joining
84 85 86 |
# File 'lib/toon/primitives.rb', line 84 def join_encoded_values(values, delimiter = COMMA) values.map { |v| encode_primitive(v, delimiter) }.join(delimiter) end |
.numeric_like?(value) ⇒ Boolean
50 51 52 53 |
# File 'lib/toon/primitives.rb', line 50 def numeric_like?(value) # Match numbers like: 42, -3.14, 1e-6, 05, etc. value.match?(/^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i) || value.match?(/^0\d+$/) end |
.padded_with_whitespace?(value) ⇒ Boolean
55 56 57 |
# File 'lib/toon/primitives.rb', line 55 def padded_with_whitespace?(value) value != value.strip end |
.safe_unquoted?(value, delimiter = COMMA) ⇒ Boolean
35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/toon/primitives.rb', line 35 def safe_unquoted?(value, delimiter = COMMA) return false if value.empty? return false if padded_with_whitespace?(value) return false if value == TRUE_LITERAL || value == FALSE_LITERAL || value == NULL_LITERAL return false if numeric_like?(value) return false if value.include?(COLON) return false if value.include?(DOUBLE_QUOTE) || value.include?(BACKSLASH) return false if value.match?(/[\[\]{}]/) return false if value.match?(/[\n\r\t]/) return false if value.include?(delimiter) return false if value.start_with?(LIST_ITEM_MARKER) true end |
.valid_unquoted_key?(key) ⇒ Boolean
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/toon/primitives.rb', line 68 def valid_unquoted_key?(key) # Keys must not contain control characters or special characters return false if key.match?(/[\n\r\t]/) return false if key.include?(COLON) return false if key.include?(DOUBLE_QUOTE) || key.include?(BACKSLASH) return false if key.match?(/[\[\]{}]/) return false if key.include?(COMMA) return false if key.start_with?(LIST_ITEM_MARKER) return false if key.empty? return false if key.match?(/^\d+$/) # Numeric keys return false if key != key.strip # Leading/trailing spaces key.match?(/^[A-Z_][\w.]*$/i) end |