async def dump_variant(self, elem, elem_type=None, params=None, obj=None):
        """
        Dumps variant type to the writer.
        Supports both wrapped and raw variant.

        :param elem:
        :param elem_type:
        :param params:
        :param obj:
        :return:
        """
        fvalue = None
        if isinstance(elem, x.VariantType) or elem_type.WRAPS_VALUE:
            try:
                self.tracker.push_variant(elem.variant_elem_type)
                fvalue = {
                    elem.variant_elem: await self._dump_field(getattr(elem, elem.variant_elem), elem.variant_elem_type, obj=obj)
                }
                self.tracker.pop()

            except Exception as e:
                raise helpers.ArchiveException(e, tracker=self.tracker) from e

        else:
            try:
                fdef = elem_type.find_fdef(elem_type.f_specs(), elem)
                self.tracker.push_variant(fdef[1])
                fvalue = {
                    fdef[0]: await self._dump_field(elem, fdef[1], obj=obj)
                }
                self.tracker.pop()

            except Exception as e:
                raise helpers.ArchiveException(e, tracker=self.tracker) from e

        return fvalue