from typing import Mapping
from typing import MutableMapping
from typing import Iterable
from typing import MutableSequence


def from_rec_avro_destructive(o):
    """
    Converts a nested data structure in rec_avro format into a python nested
    data structure. The input data structure is destroyed and reused.

    rec_avro format is conforming to the avro schema generated by rec_avro_schema()

    For fastavro::

        records = [from_rec_avro_destructive(record)
                   for record in fastavro.reader(in_stream)]

    See also::

        rec_avro_schema()
        to_rec_avro_destructive()

    :param o: data structure in rec_avro format.
    :return: plain python data structure
    """
    if isinstance(o, str):
        return o

    if isinstance(o, Mapping):
        o = o['_']
        if isinstance(o, Mapping):
            if isinstance(o, MutableMapping):
                for k, v in o.items():
                    o[k] = from_rec_avro_destructive(v)
                return o
            else:
                return {k: from_rec_avro_destructive(v) for k, v in o.items()}
        if isinstance(o, Iterable):
            if isinstance(o, MutableSequence):
                for i in range(len(o)):
                    o[i] = from_rec_avro_destructive(o[i])
                return o
            else:
                return [from_rec_avro_destructive(i) for i in o]

        raise Exception('rec_object {"_": val} val must be Mapping or Iterable')

    return o