Class: Permittable::ContractBuilder
- Inherits:
-
Object
- Object
- Permittable::ContractBuilder
- Defined in:
- lib/permittable.rb
Overview
Builds the frozen field list from the permit_params block. Every declaration is validated eagerly: a bad contract is a programmer error and should fail at class load, not at request time.
Constant Summary collapse
- SCALAR_OPTS =
%i[in format length default normalize validate virtual sensitive transform].freeze
- NESTED_OPTS =
%i[virtual sensitive].freeze
- ARRAY_OPTS =
%i[of length default validate virtual sensitive required transform].freeze
Instance Attribute Summary collapse
-
#finalizer ⇒ Object
readonly
Returns the value of attribute finalizer.
Instance Method Summary collapse
-
#array(name, **opts, &block) ⇒ Object
Array of scalars (
of:, default :string) or, with a block, an array of nested hashes. - #build(&block) ⇒ Object
-
#finalize(&block) ⇒ Object
Post-validation reshaping of the whole contract — see the module comment.
-
#initialize ⇒ ContractBuilder
constructor
A new instance of ContractBuilder.
- #optional(name, type = nil, **opts, &block) ⇒ Object
-
#required(name, type = nil, **opts, &block) ⇒ Object
required :namedefaults the type to :string.
Constructor Details
#initialize ⇒ ContractBuilder
Returns a new instance of ContractBuilder.
313 314 315 316 |
# File 'lib/permittable.rb', line 313 def initialize @fields = [] @finalizer = nil end |
Instance Attribute Details
#finalizer ⇒ Object (readonly)
Returns the value of attribute finalizer.
311 312 313 |
# File 'lib/permittable.rb', line 311 def finalizer @finalizer end |
Instance Method Details
#array(name, **opts, &block) ⇒ Object
Array of scalars (of:, default :string) or, with a block, an array
of nested hashes. Optional unless required: true; length:
constrains the element COUNT.
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/permittable.rb', line 345 def array(name, **opts, &block) name = field_name!(name) assert_opts!(name, opts, ARRAY_OPTS) required = opts.delete(:required) ? true : false field = { name: name, kind: :array, required: required, **opts } if block raise ArgumentError, "#{LABEL}: array :#{name} takes of: OR a block, not both" if opts.key?(:of) field[:fields] = nested_fields!(name, &block) field.delete(:of) else field[:of] = scalar_type!(name, opts[:of] || :string) end validate_length!(name, field[:length]) if field.key?(:length) validate_callable!(name, :validate, field[:validate]) if field.key?(:validate) validate_callable!(name, :transform, field[:transform]) if field.key?(:transform) validate_array_default!(field) if field.key?(:default) @fields << field end |
#build(&block) ⇒ Object
318 319 320 321 |
# File 'lib/permittable.rb', line 318 def build(&block) instance_eval(&block) @fields.map(&:freeze).freeze end |
#finalize(&block) ⇒ Object
Post-validation reshaping of the whole contract — see the module comment. Once per contract, top level only.
325 326 327 328 329 330 |
# File 'lib/permittable.rb', line 325 def finalize(&block) raise ArgumentError, "#{LABEL}: finalize requires a block" unless block raise ArgumentError, "#{LABEL}: finalize may only be declared once per contract" if @finalizer @finalizer = block end |
#optional(name, type = nil, **opts, &block) ⇒ Object
338 339 340 |
# File 'lib/permittable.rb', line 338 def optional(name, type = nil, **opts, &block) add_field(name, type, required: false, opts: opts, &block) end |
#required(name, type = nil, **opts, &block) ⇒ Object
required :name defaults the type to :string. A block instead of a
type declares a nested hash of sub-fields.
334 335 336 |
# File 'lib/permittable.rb', line 334 def required(name, type = nil, **opts, &block) add_field(name, type, required: true, opts: opts, &block) end |