module DataModel # Symbol type class Builtin::Symbol < Type include Errors # Arguments for this type class Arguments < Struct prop :optional, :boolean, default: false prop :included, [:array, :symbol], default: [] prop :excluded, [:array, :symbol], default: [] end # 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 # optional & missing if args.optional && val.nil? return [val, err] end if !args.optional && val.nil? err.add(missing_error(type_name)) return [val, err] end # type error if !val.is_a?(Symbol) && !coerce err.add(type_error(type_name, val)) return [val, err] end # attempt coercion if !val.is_a?(Symbol) && coerce if val.is_a?(String) val = val.intern elsif val.respond_to?(:to_sym) val = val.to_sym else err.add(coerce_error(type_name, val)) return [val, err] end end # inclusion if args.included.any? && !args.included.include?(val) err.add(inclusion_error(args.included)) return [val, err] end # exclusion if args.excluded.any? && args.excluded.include?(val) err.add(exclusion_error(args.excluded)) return [val, err] end # done return [val, err] end end end