require "date" require "bigdecimal" module Lutaml module Model module Type # This module provides a set of methods to cast and serialize values # TODO: Make Boolean a separate class %w( String Integer Float Date Time Boolean Decimal Hash ).each do |t| class_eval <<~HEREDOC, __FILE__, __LINE__ + 1 class #{t} # class Integer def self.cast(value) # def self.cast(value) return if value.nil? # return if value.nil? Type.cast(value, #{t}) # Type.cast(value, Integer) end # end def self.serialize(value) # def self.serialize(value) return if value.nil? # return if value.nil? Type.serialize(value, #{t}) # Type.serialize(value, Integer) end # end end # end HEREDOC end UUID_REGEX = /\A[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\z/ def self.cast(value, type) return if value.nil? case type.to_s.split("::").last when "String" value.to_s when "Integer" value.to_i when "Float" value.to_f when "Date" begin ::Date.parse(value.to_s) rescue ArgumentError nil end when "DateTime" DateTime.cast(value) when "Time" ::Time.parse(value.to_s) when "TimeWithoutDate" TimeWithoutDate.cast(value) when "Boolean" to_boolean(value) when "Decimal" BigDecimal(value.to_s) when "Hash" normalize_hash(Hash(value)) else value end end def self.serialize(value, type) return if value.nil? case type.to_s.split("::").last when "Date" value.iso8601 when "DateTime" DateTime.serialize(value) when "Integer" value.to_i when "Float" value.to_f when "Boolean" to_boolean(value) when "Decimal" value.to_s("F") when "Hash" Hash(value) else value.to_s end end def self.to_boolean(value) if value == true || value.to_s =~ (/^(true|t|yes|y|1)$/i) return true end if value == false || value.nil? || value.to_s =~ (/^(false|f|no|n|0)$/i) return false end raise ArgumentError.new("invalid value for Boolean: \"#{value}\"") end def self.normalize_hash(hash) return hash["text"] if hash.keys == ["text"] hash.filter_map do |key, value| next if key == "text" if value.is_a?(::Hash) [key, normalize_hash(value)] else [key, value] end end.to_h end end end end require_relative "type/time_without_date" require_relative "type/date_time"