module Crystalline

def self.marshal_dict_complex(complex)

def self.marshal_dict_complex(complex)
  if complex.is_a? Array
    complex.map { |v| Crystalline.marshal_dict_complex(v) }
  elsif complex.is_a? Hash
    complex.transform_values { |v| Crystalline.marshal_dict_complex(v) }
  elsif complex.is_a? Crystalline::FieldAugmented
    complex.to_dict
  else
    complex
  end
end

def self.marshal_json_complex(complex)

def self.marshal_json_complex(complex)
  JSON.dump(marshal_dict_complex(complex))
end

def self.unmarshal_complex(data, type)

def self.unmarshal_complex(data, type)
  unmarshal_json(data, type)
end

def self.unmarshal_json(data, type)

def self.unmarshal_json(data, type)
  if T.simplifiable? type
    type = T.simplify_type type
  end
  if type.instance_of?(Class) && type < ::Crystalline::FieldAugmented
    type.from_dict(data)
  elsif T.arr? type
    data.map { |v| Crystalline.unmarshal_complex(v, T.arr_of(type)) }
  elsif T.hash? type
    data.transform_values { |v| Crystalline.unmarshal_complex(v, T.hash_of(type)) }
  else
    data
  end
end

def self.val_to_string(val, primitives: true)

def self.val_to_string(val, primitives: true)
  if val.is_a? T::Enum
    val.serialize
  elsif val.is_a? DateTime
    val.strftime('%Y-%m-%dT%H:%M:%S.%NZ')
  elsif primitives
    val.to_s
  else
    val
  end
end