# Path: aiohttp_json_api/abc/field.py
# class FieldABC(abc.ABC):
#     @property
#     @abc.abstractmethod
#     def key(self) -> str:
#         raise NotImplementedError
# 
#     @property
#     @abc.abstractmethod
#     def sp(self) -> JSONPointer:
#         raise NotImplementedError
# 
#     @property
#     @abc.abstractmethod
#     def name(self) -> Optional[str]:
#         raise NotImplementedError
# 
#     @name.setter
#     @abc.abstractmethod
#     def name(self, value: Optional[str]):
#         pass
# 
#     @property
#     @abc.abstractmethod
#     def mapped_key(self) -> Optional[str]:
#         raise NotImplementedError
# 
#     @mapped_key.setter
#     @abc.abstractmethod
#     def mapped_key(self, value: Optional[str]):
#         pass
# 
#     @abc.abstractmethod
#     def serialize(self, schema, data, **kwargs):
#         """
#         Serialize the passed *data*.
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def deserialize(self, schema, data, sp, **kwargs):
#         """
#         Deserialize the raw *data* from the JSON API input document
#         and returns it.
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def pre_validate(self, schema, data, sp):
#         """
#         Validates the raw JSON API input for this field. This method is
#         called before :meth:`deserialize`.
# 
#         :arg ~aiohttp_json_api.schema.BaseSchema schema:
#             The schema this field has been defined on.
#         :arg data:
#             The raw input data
#         :arg ~aiohttp_json_api.jsonpointer.JSONPointer sp:
#             A JSON pointer to the source of *data*.
#         :arg ~aiohttp_json_api.context.JSONAPIContext context:
#             A JSON API request context instance
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def post_validate(self, schema, data, sp):
#         """
#         Validates the decoded input *data* for this field. This method is
#         called after :meth:`deserialize`.
# 
#         :arg ~aiohttp_json_api.schema.BaseSchema schema:
#             The schema this field has been defined on.
#         :arg data:
#             The decoded input data
#         :arg ~aiohttp_json_api.jsonpointer.JSONPointer sp:
#             A JSON pointer to the source of *data*.
#         :arg ~aiohttp_json_api.context.JSONAPIContext context:
#             A JSON API request context instance
#         """
#         raise NotImplementedError
# 
# Path: aiohttp_json_api/common.py
# ALLOWED_MEMBER_NAME_REGEX = re.compile('^' + ALLOWED_MEMBER_NAME_RULE + '$')
# 
# class Event(Flag):
#     """Request event enumeration."""
# 
#     GET = auto()
#     POST = auto()
#     PATCH = auto()
#     DELETE = auto()
#     NEVER = auto()
#     ALWAYS = GET | POST | PATCH | DELETE
#     CREATE = POST
#     UPDATE = PATCH
# 
# JSONAPI = 'jsonapi'
# 
# Path: aiohttp_json_api/errors.py
# class InvalidType(ValidationError):
#     """
#     JSON API invalid type error. HTTP 400 Bad request.
# 
#     Raised if an input value (part of a JSON API document) has the wrong type.
# 
#     This type of exception is often raised during decoding.
# 
#     :seealso: http://jsonapi.org/format/#document-structure
#     """
# 
# class InvalidValue(ValidationError):
#     """
#     JSON API invalid value error. HTTP 400 Bad request.
# 
#     Raised if an input value (part of a JSON API document) has an invalid
#     value.
# 
#     :seealso: http://jsonapi.org/format/#document-structure
#     """
# 
# Path: aiohttp_json_api/jsonpointer.py
# class JSONPointer(BaseJsonPointer):
#     def __truediv__(self,
#                     path: typing.Union['JSONPointer', str]) -> 'JSONPointer':
#         parts = self.parts.copy()
# 
#         if isinstance(path, int):
#             path = str(path)
# 
#         if isinstance(path, str):
#             if not path.startswith('/'):
#                 path = f'/{path}'
#             new_parts = JSONPointer(path).parts.pop(0)
#             parts.append(new_parts)
#         else:
#             new_parts = path.parts
#             parts.extend(new_parts)
#         return JSONPointer.from_parts(parts)


import urllib.parse
from collections import Mapping
from typing import Optional, Sequence
from ..abc.field import FieldABC
from ..common import ALLOWED_MEMBER_NAME_REGEX, Event, JSONAPI
from ..errors import InvalidType, InvalidValue
from ..jsonpointer import JSONPointer
    (via :mod:`~aiohttp_json_api.schema.decorators`).

    .. hint::

        The inheritance of fields is currently implemented using the
        :func:`~copy.deepcopy` function from the standard library. This means,
        that in some rare cases, it is necessarily that you implement a
        custom :meth:`__deepcopy__` method when you subclass
        :class:`BaseField`.

    :arg str name:
        The name of the field in the JSON API document. If not explicitly
        given, it's the same as :attr:`key`.
    :arg str mapped_key:
        The name of the associated property on the resource class. If not
        explicitly given, it's the same as :attr:`key`.
    :arg bool allow_none:
        Allow to receive 'null' value
    :arg Event writable:
        Can be any :class:`~aiohttp_json_api.schema.common.Event`
        enumeration value and describes in which CRUD context the field
        is writable.
    :arg Event required:
        Can be any :class:`~aiohttp_json_api.schema.common.Event`
        enumeration value and describes in which CRUD context the field
        is required as input.
    """

    def __init__(self, *, name: str = None, mapped_key: str = None,
                 allow_none: bool = False,

# Path: aiohttp_json_api/abc/field.py
# class FieldABC(abc.ABC):
#     @property
#     @abc.abstractmethod
#     def key(self) -> str:
#         raise NotImplementedError
# 
#     @property
#     @abc.abstractmethod
#     def sp(self) -> JSONPointer:
#         raise NotImplementedError
# 
#     @property
#     @abc.abstractmethod
#     def name(self) -> Optional[str]:
#         raise NotImplementedError
# 
#     @name.setter
#     @abc.abstractmethod
#     def name(self, value: Optional[str]):
#         pass
# 
#     @property
#     @abc.abstractmethod
#     def mapped_key(self) -> Optional[str]:
#         raise NotImplementedError
# 
#     @mapped_key.setter
#     @abc.abstractmethod
#     def mapped_key(self, value: Optional[str]):
#         pass
# 
#     @abc.abstractmethod
#     def serialize(self, schema, data, **kwargs):
#         """
#         Serialize the passed *data*.
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def deserialize(self, schema, data, sp, **kwargs):
#         """
#         Deserialize the raw *data* from the JSON API input document
#         and returns it.
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def pre_validate(self, schema, data, sp):
#         """
#         Validates the raw JSON API input for this field. This method is
#         called before :meth:`deserialize`.
# 
#         :arg ~aiohttp_json_api.schema.BaseSchema schema:
#             The schema this field has been defined on.
#         :arg data:
#             The raw input data
#         :arg ~aiohttp_json_api.jsonpointer.JSONPointer sp:
#             A JSON pointer to the source of *data*.
#         :arg ~aiohttp_json_api.context.JSONAPIContext context:
#             A JSON API request context instance
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def post_validate(self, schema, data, sp):
#         """
#         Validates the decoded input *data* for this field. This method is
#         called after :meth:`deserialize`.
# 
#         :arg ~aiohttp_json_api.schema.BaseSchema schema:
#             The schema this field has been defined on.
#         :arg data:
#             The decoded input data
#         :arg ~aiohttp_json_api.jsonpointer.JSONPointer sp:
#             A JSON pointer to the source of *data*.
#         :arg ~aiohttp_json_api.context.JSONAPIContext context:
#             A JSON API request context instance
#         """
#         raise NotImplementedError
# 
# Path: aiohttp_json_api/common.py
# ALLOWED_MEMBER_NAME_REGEX = re.compile('^' + ALLOWED_MEMBER_NAME_RULE + '$')
# 
# class Event(Flag):
#     """Request event enumeration."""
# 
#     GET = auto()
#     POST = auto()
#     PATCH = auto()
#     DELETE = auto()
#     NEVER = auto()
#     ALWAYS = GET | POST | PATCH | DELETE
#     CREATE = POST
#     UPDATE = PATCH
# 
# JSONAPI = 'jsonapi'
# 
# Path: aiohttp_json_api/errors.py
# class InvalidType(ValidationError):
#     """
#     JSON API invalid type error. HTTP 400 Bad request.
# 
#     Raised if an input value (part of a JSON API document) has the wrong type.
# 
#     This type of exception is often raised during decoding.
# 
#     :seealso: http://jsonapi.org/format/#document-structure
#     """
# 
# class InvalidValue(ValidationError):
#     """
#     JSON API invalid value error. HTTP 400 Bad request.
# 
#     Raised if an input value (part of a JSON API document) has an invalid
#     value.
# 
#     :seealso: http://jsonapi.org/format/#document-structure
#     """
# 
# Path: aiohttp_json_api/jsonpointer.py
# class JSONPointer(BaseJsonPointer):
#     def __truediv__(self,
#                     path: typing.Union['JSONPointer', str]) -> 'JSONPointer':
#         parts = self.parts.copy()
# 
#         if isinstance(path, int):
#             path = str(path)
# 
#         if isinstance(path, str):
#             if not path.startswith('/'):
#                 path = f'/{path}'
#             new_parts = JSONPointer(path).parts.pop(0)
#             parts.append(new_parts)
#         else:
#             new_parts = path.parts
#             parts.extend(new_parts)
#         return JSONPointer.from_parts(parts)


# Path: aiohttp_json_api/fields/base.py
import urllib.parse
from collections import Mapping
from typing import Optional, Sequence
from ..abc.field import FieldABC
from ..common import ALLOWED_MEMBER_NAME_REGEX, Event, JSONAPI
from ..errors import InvalidType, InvalidValue
from ..jsonpointer import JSONPointer

    (via :mod:`~aiohttp_json_api.schema.decorators`).

    .. hint::

        The inheritance of fields is currently implemented using the
        :func:`~copy.deepcopy` function from the standard library. This means,
        that in some rare cases, it is necessarily that you implement a
        custom :meth:`__deepcopy__` method when you subclass
        :class:`BaseField`.

    :arg str name:
        The name of the field in the JSON API document. If not explicitly
        given, it's the same as :attr:`key`.
    :arg str mapped_key:
        The name of the associated property on the resource class. If not
        explicitly given, it's the same as :attr:`key`.
    :arg bool allow_none:
        Allow to receive 'null' value
    :arg Event writable:
        Can be any :class:`~aiohttp_json_api.schema.common.Event`
        enumeration value and describes in which CRUD context the field
        is writable.
    :arg Event required:
        Can be any :class:`~aiohttp_json_api.schema.common.Event`
        enumeration value and describes in which CRUD context the field
        is required as input.
    """

    def __init__(self, *, name: str = None, mapped_key: str = None,
                 allow_none: bool = False,

                 writable: Event = Event.ALWAYS,