Module: IknowParams::Parser
Overview
IknowParams::Parser provides a mix-in for ActiveRecord controllers to parse input parameters.
Defined Under Namespace
Classes: HashParser, ParseError
Constant Summary collapse
- PARAM_REQUIRED =
Object.new
- BLANK =
Object.new
Class Method Summary collapse
- .parse_hash(hash, &block) ⇒ Object
- .parse_value(value, **args) ⇒ Object
- .parse_values(values, **args) ⇒ Object
-
.register_serializer(name, serializer) ⇒ Object
Allow serializers to register themselves.
Instance Method Summary collapse
-
#parse_array_param(param, with: nil, default: PARAM_REQUIRED, dump: false) ⇒ Object
Parse an array-typed param using the provided serializer for each member element.
-
#parse_param(param, with: nil, default: PARAM_REQUIRED, dump: false) ⇒ Object
Parse the specified parameter, optionally deserializing with the provided IKnowParams::Serializer.
-
#remove_blanks(arg) ⇒ Object
Convenience method to make it simpler to build a hash structure with optional members from parsed data.
Class Method Details
.parse_hash(hash, &block) ⇒ Object
27 28 29 |
# File 'lib/iknow_params/parser.rb', line 27 def parse_hash(hash, &block) HashParser.new(hash).parse(&block) end |
.parse_value(value, **args) ⇒ Object
31 32 33 |
# File 'lib/iknow_params/parser.rb', line 31 def parse_value(value, **args) HashParser.new({ sentinel: value }).parse_param(:sentinel, **args) end |
.parse_values(values, **args) ⇒ Object
35 36 37 |
# File 'lib/iknow_params/parser.rb', line 35 def parse_values(values, **args) HashParser.new({ sentinel: values }).parse_array_param(:sentinel, **args) end |
.register_serializer(name, serializer) ⇒ Object
Allow serializers to register themselves
146 147 148 149 150 151 152 153 |
# File 'lib/iknow_params/parser.rb', line 146 def self.register_serializer(name, serializer) define_method(:"parse_#{name.underscore}_param") do |param, default: PARAM_REQUIRED| parse_param(param, with: serializer, default: default) end define_method(:"parse_#{name.underscore}_array_param") do |param, default: PARAM_REQUIRED| parse_array_param(param, with: serializer, default: default) end end |
Instance Method Details
#parse_array_param(param, with: nil, default: PARAM_REQUIRED, dump: false) ⇒ Object
Parse an array-typed param using the provided serializer for each member element.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/iknow_params/parser.rb', line 89 def parse_array_param(param, with: nil, default: PARAM_REQUIRED, dump: false) serializer = case with when String, Symbol IknowParams::Serializer.for!(with) else with end vals = params[param] parses = if vals.nil? raise ParseError.new("Required parameter '#{param}' missing", param, nil) if default == PARAM_REQUIRED default elsif !vals.is_a?(Array) raise ParseError.new("Invalid type for parameter '#{param}': '#{vals.class.name}'", param, vals) elsif serializer.present? vals.map do |val| begin serializer.load(val) rescue IknowParams::Serializer::LoadError => ex raise ParseError.new("Invalid member in array parameter '#{param}': '#{val.inspect}' - #{ex.}", param, val) end end else vals end if dump && parses != BLANK parses.map! { |v| serializer.dump(v) } end parses end |
#parse_param(param, with: nil, default: PARAM_REQUIRED, dump: false) ⇒ Object
Parse the specified parameter, optionally deserializing with the provided IKnowParams::Serializer. If the parameter is missing and no default is provided, raises a ParseError.
If BLANK is provided as a default, return a placeholder object that can be later stripped out with remove_blanks
If dump is true, use the serializer to re-serialize any successfully parsed argument back to a canonical string. This can be useful to validate and normalize the input to another service without parsing it. A serializer must be passed to use this option.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/iknow_params/parser.rb', line 51 def parse_param(param, with: nil, default: PARAM_REQUIRED, dump: false) serializer = case with when String, Symbol IknowParams::Serializer.for!(with) else with end parse = if !params.has_key?(param) raise ParseError.new("Required parameter '#{param}' missing", param, nil) if default == PARAM_REQUIRED default else val = params[param] if serializer.present? begin serializer.load(val) rescue IknowParams::Serializer::LoadError => ex raise ParseError.new("Invalid parameter '#{param}': '#{val.inspect}' - #{ex.}", param, val) end else val end end if dump && parse != BLANK begin parse = serializer.dump(parse) rescue NoMethodError => ex raise ParseError.new("Serializer '#{serializer}' can't dump param '#{param}' #{val.inspect} - #{ex.}", param, val) end end parse end |
#remove_blanks(arg) ⇒ Object
Convenience method to make it simpler to build a hash structure with optional members from parsed data. This method recursively traverses the provided structure and removes any instances of the sentinel value Parser::BLANK.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/iknow_params/parser.rb', line 129 def remove_blanks(arg) case arg when Hash arg.each do |k, v| if v == BLANK arg.delete(k) else remove_blanks(v) end end when Array arg.delete(BLANK) arg.each { |e| remove_blanks(e) } end end |