module ReeDto::EntityDSL::ClassMethods

def properties(**args)

def properties(**args)
  args.each do |name, contract_class|
    contract None => contract_class
    class_eval %Q(
      def #{name}
        @#{name}
      end
    )
  end
  contract Kwargs[**args] => Any
  class_eval %Q(
    def initialize(#{args.keys.map {|k| "#{k}: nil"}.join(',')})
      #{
        args.map {|k, v|
          "@#{k} = #{k}"
        }.join("\n")
      }
    end
    contract Any => Bool
    def ==(val)
      return false unless val.is_a?(self.class)
      #{
        args.map {|k, _|
          "@#{k} == val.#{k}"
        }.join(" && ")
      }
    end
    def to_h
      {
        #{args.map {|k, _| "#{k}: #{k}" }.join(", ")}
      }
    end
    def values_for(*args)
      args.map do |arg|
        variable = ("@" + arg.to_s).to_sym
        if !instance_variables.include?(variable)
          raise ArgumentError.new("variable :" + arg.to_s + " not found in dto")
        end
        instance_variable_get(variable)
      end
    end
    class << self
      def import_from(other_dto)
        self.new(
          #{
            args.map {|k, v|
              "#{k}: other_dto.#{k}"
            }.join(",")
          }
        )
      end
    end
  )
  nil
end