Class: Opto::Option
- Inherits:
-
Object
- Object
- Opto::Option
- Defined in:
- lib/opto/option.rb
Overview
What is an option? It’s like a variable that has a value, which can be validated or manipulated on creation. The value can be resolved from a number of origins, such as an environment variable or random string generator.
Instance Attribute Summary collapse
-
#default ⇒ Object
Returns the value of attribute default.
-
#description ⇒ Object
Returns the value of attribute description.
-
#from ⇒ Object
readonly
Returns the value of attribute from.
-
#group ⇒ Object
readonly
Returns the value of attribute group.
-
#initial_value ⇒ Object
readonly
Returns the value of attribute initial_value.
-
#label ⇒ Object
Returns the value of attribute label.
-
#name ⇒ Object
Returns the value of attribute name.
-
#only_if ⇒ Object
readonly
Returns the value of attribute only_if.
-
#required ⇒ Object
Returns the value of attribute required.
-
#skip_if ⇒ Object
readonly
Returns the value of attribute skip_if.
-
#to ⇒ Object
readonly
Returns the value of attribute to.
-
#type ⇒ Object
Returns the value of attribute type.
-
#type_options ⇒ Object
readonly
Returns the value of attribute type_options.
Instance Method Summary collapse
- #deep_merge_defaults ⇒ Object
-
#errors ⇒ Hash
Validation errors.
-
#handler ⇒ Opto::Type
Access the Opto::Type handler for this option.
- #has_group? ⇒ Boolean
-
#initialize(options = {}) ⇒ Option
constructor
Initialize an instance of Opto::Option.
- #normalize_from_to(inputs) ⇒ Object
-
#output ⇒ Object
Run setters.
-
#required? ⇒ Boolean
True if this field is defined as required: true.
-
#resolve ⇒ Object
Run resolvers.
-
#resolvers ⇒ Array<Opto::Resolver>
Accessor to defined resolvers for this option.
-
#set(value) ⇒ Object
(also: #value=)
Set option value.
- #set_tried ⇒ Object
- #setters ⇒ Object
-
#skip? ⇒ Boolean
Returns true if this field should not be processed because of the conditionals.
-
#to_h(with_errors: false, with_value: true) ⇒ Hash
Hash representation of Opto::Option.
- #tried_resolve? ⇒ Boolean
- #true? ⇒ Boolean
- #unset_tried! ⇒ Object
-
#valid? ⇒ Boolean
True if value is valid.
-
#validate ⇒ Object
Run validators.
-
#value ⇒ Object
The value of this option.
-
#value_of(option_name) ⇒ Object
Get a value of another Opto::Group member.
Constructor Details
#initialize(options = {}) ⇒ Option
Initialize an instance of Opto::Option
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/opto/option.rb', line 68 def initialize( = {}) opts = .dup @group = opts.delete(:group) if @group && @group.defaults opts = @group.defaults.reject{|k,_| [:from, :to].include?(k)}.merge(opts) end @name = opts.delete(:name).to_s type = opts.delete(:type) @type = type.to_s.snakecase unless type.nil? @label = opts.delete(:label) || @name @description = opts.delete(:description) @default = opts.delete(:default) val = opts.delete(:value) @skip_if = opts.delete(:skip_if) @only_if = opts.delete(:only_if) @from = normalize_from_to(opts.delete(:from)) @to = normalize_from_to(opts.delete(:to)) validations = opts.delete(:validate).to_h transforms = opts.delete(:transform) transforms = case transforms when NilClass then {} when Hash then transforms when Array then transforms.each_with_object({}) { |t, hash| hash[t] = true } else raise TypeError, 'Transform has to be a hash or an array' end @type_options = opts.merge(validations).merge(transforms) @tried_resolve = false set_initial(val) if val deep_merge_defaults end |
Instance Attribute Details
#default ⇒ Object
Returns the value of attribute default.
21 22 23 |
# File 'lib/opto/option.rb', line 21 def default @default end |
#description ⇒ Object
Returns the value of attribute description.
19 20 21 |
# File 'lib/opto/option.rb', line 19 def description @description end |
#from ⇒ Object (readonly)
Returns the value of attribute from.
22 23 24 |
# File 'lib/opto/option.rb', line 22 def from @from end |
#group ⇒ Object (readonly)
Returns the value of attribute group.
24 25 26 |
# File 'lib/opto/option.rb', line 24 def group @group end |
#initial_value ⇒ Object (readonly)
Returns the value of attribute initial_value.
27 28 29 |
# File 'lib/opto/option.rb', line 27 def initial_value @initial_value end |
#label ⇒ Object
Returns the value of attribute label.
18 19 20 |
# File 'lib/opto/option.rb', line 18 def label @label end |
#name ⇒ Object
Returns the value of attribute name.
17 18 19 |
# File 'lib/opto/option.rb', line 17 def name @name end |
#only_if ⇒ Object (readonly)
Returns the value of attribute only_if.
26 27 28 |
# File 'lib/opto/option.rb', line 26 def only_if @only_if end |
#required ⇒ Object
Returns the value of attribute required.
20 21 22 |
# File 'lib/opto/option.rb', line 20 def required @required end |
#skip_if ⇒ Object (readonly)
Returns the value of attribute skip_if.
25 26 27 |
# File 'lib/opto/option.rb', line 25 def skip_if @skip_if end |
#to ⇒ Object (readonly)
Returns the value of attribute to.
23 24 25 |
# File 'lib/opto/option.rb', line 23 def to @to end |
#type ⇒ Object
Returns the value of attribute type.
16 17 18 |
# File 'lib/opto/option.rb', line 16 def type @type end |
#type_options ⇒ Object (readonly)
Returns the value of attribute type_options.
28 29 30 |
# File 'lib/opto/option.rb', line 28 def @type_options end |
Instance Method Details
#deep_merge_defaults ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/opto/option.rb', line 110 def deep_merge_defaults return nil unless group && group.defaults if group.defaults[:from] normalize_from_to(group.defaults[:from]).each do |k,v| from[k] ||= v end end if group.defaults[:to] normalize_from_to(group.defaults[:to]).each do |k,v| to[k] ||= v end end end |
#errors ⇒ Hash
Validation errors
285 286 287 |
# File 'lib/opto/option.rb', line 285 def errors handler.errors end |
#handler ⇒ Opto::Type
Access the Opto::Type handler for this option
188 189 190 191 192 |
# File 'lib/opto/option.rb', line 188 def handler @handler ||= Type.for(type).new() rescue StandardError => ex raise ex, "#{name}: #{ex.}" end |
#has_group? ⇒ Boolean
106 107 108 |
# File 'lib/opto/option.rb', line 106 def has_group? !group.nil? end |
#normalize_from_to(inputs) ⇒ Object
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/opto/option.rb', line 289 def normalize_from_to(inputs) case inputs when ::Array case inputs.first when String, Symbol inputs.each_with_object({}) { |o, hash| hash[o.to_s.snakecase.to_sym] = name } when Hash inputs.each_with_object({}) { |o, hash| o.each { |k,v| hash[k.to_s.snakecase.to_sym] = v } } when NilClass {} else raise TypeError, "Invalid format #{inputs.inspect}" end when Hash inputs.each_with_object({}) { |(k, v), hash| hash[k.to_s.snakecase.to_sym] = v } when String, Symbol { inputs.to_s.snakecase.to_sym => name } when NilClass {} else raise TypeError, "Invalid format #{inputs.inspect}" end end |
#output ⇒ Object
Run setters
257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/opto/option.rb', line 257 def output setters.each do |setter_config| begin setter = setter_config[:setter] if setter.respond_to?(:call) setter.call(setter_config[:hint], value, self) else setter.new(setter_config[:hint], self).set(value) end rescue StandardError => ex raise ex, "Setter '#{setter_config[:target]}' for '#{name}' : #{ex.}" end end end |
#required? ⇒ Boolean
True if this field is defined as required: true
215 216 217 |
# File 'lib/opto/option.rb', line 215 def required? handler.required? end |
#resolve ⇒ Object
Run resolvers
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/opto/option.rb', line 233 def resolve return nil if tried_resolve? resolvers.each do |resolver_config| begin resolver = resolver_config[:resolver] if resolver.respond_to?(:call) result = resolver.call(resolver_config[:hint], self) else result = resolver.new(resolver_config[:hint], self).resolve end rescue StandardError => ex raise ex, "Resolver '#{resolver_config[:origin]}' for '#{name}' : #{ex.}" end unless result.nil? @origin = resolver_config[:origin] return result end end nil ensure set_tried end |
#resolvers ⇒ Array<Opto::Resolver>
Accessor to defined resolvers for this option.
205 206 207 |
# File 'lib/opto/option.rb', line 205 def resolvers @resolvers ||= from.merge(default: self).map { |origin, hint| { origin: origin, hint: hint, resolver: ((has_group? && group.resolvers[origin]) || Resolver.for(origin)) } } end |
#set(value) ⇒ Object Also known as: value=
Set option value. Also aliased as #value=
153 154 155 156 157 |
# File 'lib/opto/option.rb', line 153 def set(value) @value = handler.sanitize(value) validate @value end |
#set_tried ⇒ Object
223 224 225 |
# File 'lib/opto/option.rb', line 223 def set_tried @tried_resolve = true end |
#setters ⇒ Object
209 210 211 |
# File 'lib/opto/option.rb', line 209 def setters @setters ||= to.map { |target, hint| { target: target, hint: hint, setter: ((has_group? && group.setters[target]) || Setter.for(target)) } } end |
#skip? ⇒ Boolean
Returns true if this field should not be processed because of the conditionals
163 164 165 166 167 168 |
# File 'lib/opto/option.rb', line 163 def skip? return false unless has_group? return true if group.any_true?(skip_if) return true unless group.all_true?(only_if) false end |
#to_h(with_errors: false, with_value: true) ⇒ Hash
Hash representation of Opto::Option. Can be passed back to Opto::Option.new
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/opto/option.rb', line 128 def to_h(with_errors: false, with_value: true) hash = { name: name, label: label, type: type, description: description, default: default, from: from.reject { |k,_| k == :default}, to: to }.merge().reject { |_,v| v.nil? } hash[:skip_if] = skip_if if skip_if hash[:only_if] = only_if if only_if hash[:errors] = errors if with_errors if with_value if type == 'group' hash[:value] = value.to_h(with_values: true, with_errors: with_errors) else hash[:value] = value end end hash end |
#tried_resolve? ⇒ Boolean
219 220 221 |
# File 'lib/opto/option.rb', line 219 def tried_resolve? @tried_resolve end |
#true? ⇒ Boolean
279 280 281 |
# File 'lib/opto/option.rb', line 279 def true? handler.truthy?(value) end |
#unset_tried! ⇒ Object
227 228 229 |
# File 'lib/opto/option.rb', line 227 def unset_tried! @tried_resolve = false end |
#valid? ⇒ Boolean
True if value is valid
274 275 276 277 |
# File 'lib/opto/option.rb', line 274 def valid? return true if skip? handler.valid?(value) end |
#validate ⇒ Object
Run validators
180 181 182 183 184 |
# File 'lib/opto/option.rb', line 180 def validate handler.validate(@value) rescue StandardError => ex raise ex, "Validation for #{name} : #{ex.}" end |
#value ⇒ Object
The value of this option. Will try to run resolvers.
196 197 198 199 200 201 |
# File 'lib/opto/option.rb', line 196 def value return @value unless @value.nil? return nil if skip? set(resolve) @value end |
#value_of(option_name) ⇒ Object
Get a value of another Opto::Group member
172 173 174 175 176 |
# File 'lib/opto/option.rb', line 172 def value_of(option_name) return value if option_name == self.name return nil unless has_group? group.value_of(option_name) end |