lib/data_model/builtin/array.rb in data_model-0.4.0 vs lib/data_model/builtin/array.rb in data_model-0.5.0

- old
+ new

@@ -1,64 +1,71 @@ -# typed: strict - module DataModel + # Array is a type that contains a list of other types. + # + # @example + # [:array, :string] # shorthand + # [:array, [:string, {optional: true}]] class Builtin::Array < Type include Errors - class Arguments < T::Struct - prop :optional, T::Boolean, default: false - prop :wrap_single_value, T::Boolean, default: false - prop :min, T.nilable(T.any(Integer, Float, Rational, BigDecimal)), default: nil - prop :max, T.nilable(T.any(Integer, Float, Rational, BigDecimal)), default: nil - prop :length, T.nilable(T.any(Integer, Float, Rational, BigDecimal)), default: nil + # Arguments for Array type. + class Arguments < Struct + prop :optional, :boolean, default: false + prop :wrap_single_value, :boolean, default: false + prop :min, :integer, default: nil + prop :max, :integer, default: nil + prop :length, :integer, default: nil end - # support either :string shorthand or [:string, {optional: true}] - sig { override.params(params: T::Array[Object]).void } + # get the child Type + # @return [Type] the child type + attr_reader :child_type + + # configure how children will be read + # @param params [Array] the params to configure + # @return [void] def configure(params) if params.first.is_a?(Array) params = params.first end - params = T.cast(params, TSchema) node = Scanner.scan(params) type = instantiate(node.type, args: node.args, params: node.params) - @child_type = T.let(type, T.nilable(Type)) + @child_type = type end - sig { returns(Type) } - def child_type - if @child_type.nil? - raise "children not configured" - end - - return @child_type - end - - sig { override.params(val: Object, coerce: T::Boolean).returns(TTypeResult) } + # read a value, and validate it + # @param val [Object] the value to read + # @param coerce [Boolean] whether to coerce the value + # @return [Array(Object, Error)] the result of reading the value def read(val, coerce: false) args = Arguments.new(type_args) err = Error.new if val.nil? && !args.optional - err.add(missing_error(Array)) + err.add(missing_error(type_name)) return [val, err] end if coerce && args.wrap_single_value val = Array(val) end if !val.is_a?(Array) - err.add(type_error(Array, val)) + err.add(type_error(type_name, val)) return [val, err] end + # no child type configured, allow any array + if child_type.nil? + return [val, err] + end + coerced = [] for i in 0...val.length - child_val = T.let(val[i], Object) + child_val = val[i] child, child_err = child_type.read(child_val, coerce:) if child_err err.merge_child(i.to_s.to_sym, child_err) end coerced << child