Module: LabelZoom::Options
- Defined in:
- lib/labelzoom/options.rb
Overview
Renders conversion options as the params JSON value.
Everything travels in one ?params=<JSON> parameter, never dot-notation. The API accepts both and merges them, but dot-notation cannot express every parameter -- ?data=[{}] is rejected with 400 while ?params={"data":[{}]} succeeds. One serialization path, no special cases.
Constant Summary collapse
- NESTED_KEYS =
Nested option hashes, and the wire key each of their keys maps to. Anything not listed raises rather than being dropped: Ruby has no compiler to catch
label: { widht: 4 }, and the server ignores unknown keys, so a silent drop would hand the caller a wrong label and no signal. { position: { x: "x", y: "y" }, label: { width: "width", height: "height" }, pdf: { conversion_mode: "conversionMode", page_number: "pageNumber" }, zpl: { commands_to_ignore: "commandsToIgnore", image_compression: "imageCompression" } }.freeze
- SCALAR_KEYS =
{ dpi: "dpi", rotation: "rotation", scaling: "scaling", color_mode: "colorMode", darkness: "darkness", watermark: "watermark", dialect: "dialect" }.freeze
Class Method Summary collapse
- .describe(value) ⇒ Object
- .nested(key, value, mapping) ⇒ Object
-
.normalize_data(value) ⇒ Object
datais always an array -- one entry produces one label. -
.serialize(**options) ⇒ String?
The params JSON, or nil when nothing was set -- in which case no query parameter is emitted at all (rule C7).
- .stringify(hash) ⇒ Object
- .validate_scalar(key, value) ⇒ Object
Class Method Details
.describe(value) ⇒ Object
133 134 135 136 137 138 139 140 141 142 |
# File 'lib/labelzoom/options.rb', line 133 def describe(value) case value when nil then "null" when Array then "an array" when String then "a string" when Numeric then "a number" when true, false then "a boolean" else "a #{value.class}" end end |
.nested(key, value, mapping) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/labelzoom/options.rb', line 92 def nested(key, value, mapping) unless value.is_a?(Hash) raise ValidationError.new(key.to_s, "#{key} must be a Hash, but was #{describe(value)}.") end value.each_with_object({}) do |(nested_key, nested_value), out| wire_key = mapping[nested_key.to_sym] unless wire_key raise ValidationError.new(key.to_s, "#{key}[#{nested_key.inspect}] is not a recognized option. " \ "Expected one of: #{mapping.keys.join(", ")}.") end next if UNSET.equal?(nested_value) out[wire_key] = nested_value.is_a?(Symbol) ? nested_value.to_s : nested_value end end |
.normalize_data(value) ⇒ Object
data is always an array -- one entry produces one label. A caller passing a single
record means "one label", so a bare Hash is wrapped rather than rejected.
112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/labelzoom/options.rb', line 112 def normalize_data(value) records = value.is_a?(Array) ? value : [value] records.each_with_index.map do |record, index| unless record.is_a?(Hash) raise ValidationError.new("data", "data[#{index}] is #{describe(record)}; every entry must be " \ "an object whose keys are the label's variable field names.") end stringify(record) end end |
.serialize(**options) ⇒ String?
Returns the params JSON, or nil when nothing was set -- in which case no query parameter is emitted at all (rule C7).
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/labelzoom/options.rb', line 49 def serialize(**) params = {} SCALAR_KEYS.each do |key, wire_key| value = .fetch(key, UNSET) next if UNSET.equal?(value) params[wire_key] = validate_scalar(key, value) end NESTED_KEYS.each do |key, mapping| value = .fetch(key, UNSET) next if UNSET.equal?(value) params[key.to_s] = nested(key, value, mapping) end data = .fetch(:data, UNSET) params["data"] = normalize_data(data) unless UNSET.equal?(data) extra = .fetch(:extra, UNSET) params.merge!(stringify(extra)) unless UNSET.equal?(extra) params.empty? ? nil : JSON.generate(params) end |
.stringify(hash) ⇒ Object
125 126 127 128 129 130 131 |
# File 'lib/labelzoom/options.rb', line 125 def stringify(hash) unless hash.is_a?(Hash) raise ValidationError.new("extra", "extra must be a Hash, but was #{describe(hash)}.") end hash.each_with_object({}) { |(key, value), out| out[key.to_s] = value } end |
.validate_scalar(key, value) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/labelzoom/options.rb', line 75 def validate_scalar(key, value) case key when :rotation # Rejected locally: the server would 400, and this is unambiguously a caller bug. unless value.is_a?(Numeric) && (value % 90).zero? raise ValidationError.new("rotation", "Rotation must be a multiple of 90 degrees, but was #{value}.") end when :darkness unless value.is_a?(Numeric) && value.between?(0, 100) raise ValidationError.new("darkness", "Darkness must be between 0 and 100, but was #{value}.") end end value.is_a?(Symbol) ? value.to_s : value end |