# Path: lepo/apidef/parameter/base.py
# NO_VALUE = object()
# 
# class BaseParameter:
#     def __init__(self, data, api=None):
#         self.data = data
#         self.api = api
# 
#     def __repr__(self):
#         return f'<{self.__class__.__name__} ({self.data!r})>'
# 
#     @property
#     def location(self):
#         return self.data['in']
# 
#     @property
#     def required(self):
#         return bool(self.data.get('required'))
# 
#     @property
#     def items(self):
#         return self.data.get('items')
# 
#     def cast(self, api, value):  # pragma: no cover
#         raise NotImplementedError('Subclasses must implement cast')
# 
#     def get_value(self, request, view_kwargs):  # pragma: no cover
#         """
#         :type request: WSGIRequest
#         :type view_kwargs: dict
#         """
#         raise NotImplementedError('Subclasses must implement get_value')
# 
# class BaseTopParameter(BaseParameter):
#     """
#     Top-level Parameter, such as in an operation
#     """
# 
#     def __init__(self, data, api=None, operation=None):
#         super().__init__(data, api=api)
#         self.operation = operation
# 
#     @property
#     def name(self):
#         return self.data['name']
# 
#     @property
#     def in_body(self):
#         return self.location in ('formData', 'body')
# 
#     def get_value(self, request, view_kwargs):
#         raise InvalidParameterDefinition(f'unsupported `in` value {self.location!r} in {self!r}')  # pragma: no cover
# 
# Path: lepo/apidef/parameter/utils.py
# def comma_split(value):
#     return force_str(value).split(',')
# 
# def pipe_split(value):
#     return force_str(value).split('|')
# 
# def read_body(request, parameter=None):
#     if parameter:
#         if parameter.type == 'binary':
#             return request.body.read()
#     try:
#         if request.content_type == 'multipart/form-data':
#             # TODO: this definitely doesn't handle multiple values for the same key correctly
#             data = dict()
#             data.update(request.POST.items())
#             data.update(request.FILES.items())
#             return data
#         decoder = get_decoder(request.content_type)
#         if decoder:
#             return decoder(request.body, encoding=request.content_params.get('charset', 'UTF-8'))
#     except Exception as exc:
#         raise InvalidBodyContent(f'Unable to parse this body as {request.content_type}') from exc
#     raise NotImplementedError(f'No idea how to parse content-type {request.content_type}')  # pragma: no cover
# 
# def space_split(value):
#     return force_str(value).split(' ')
# 
# def tab_split(value):
#     return force_str(value).split('\t')
# 
# def validate_schema(schema, api, value):
#     schema = maybe_resolve(schema, resolve=api.resolve_reference)
#     jsonschema.validate(
#         value,
#         schema,
#         cls=LepoDraft4Validator,
#         resolver=api.resolver,
#     )
#     if 'discriminator' in schema:  # Swagger/OpenAPI 3 Polymorphism support
#         discriminator = schema['discriminator']
#         if isinstance(discriminator, dict):  # OpenAPI 3
#             type = value[discriminator['propertyName']]
#             if 'mapping' in discriminator:
#                 actual_type = discriminator['mapping'][type]
#             else:
#                 actual_type = f'#/components/schemas/{type}'
#         else:
#             type = value[discriminator]
#             actual_type = f'#/definitions/{type}'
#         schema = api.resolve_reference(actual_type)
#         jsonschema.validate(
#             value,
#             schema,
#             cls=LepoDraft4Validator,
#             resolver=api.resolver,
#         )
#     return value
# 
# Path: lepo/excs.py
# class InvalidBodyFormat(ValueError):
#     pass
# 
# Path: lepo/parameter_utils.py
# def cast_primitive_value(type, format, value):
#     if type == 'boolean':
#         return (force_str(value).lower() in ('1', 'yes', 'true'))
#     if type == 'integer' or format in ('integer', 'long'):
#         return int(value)
#     if type == 'number' or format in ('float', 'double'):
#         return float(value)
#     if format == 'byte':  # base64 encoded characters
#         return base64.b64decode(value)
#     if format == 'binary':  # any sequence of octets
#         return force_bytes(value)
#     if format == 'date':  # ISO8601 date
#         return iso8601.parse_date(value).date()
#     if format == 'dateTime':  # ISO8601 datetime
#         return iso8601.parse_date(value)
#     if type == 'string':
#         return force_str(value)
#     return value
# 
# Path: lepo/utils.py
# def maybe_resolve(object, resolve):
#     """
#     Call `resolve` on the `object`'s `$ref` value if it has one.
# 
#     :param object: An object.
#     :param resolve: A resolving function.
#     :return: An object, or some other object! :sparkles:
#     """
#     if isinstance(object, dict) and object.get('$ref'):
#         return resolve(object['$ref'])
#     return object


import jsonschema
from lepo.apidef.parameter.base import NO_VALUE, BaseParameter, BaseTopParameter
from lepo.apidef.parameter.utils import (
    comma_split,
    pipe_split,
    read_body,
    space_split,
    tab_split,
    validate_schema,
)
from lepo.excs import InvalidBodyFormat
from lepo.parameter_utils import cast_primitive_value
from lepo.utils import maybe_resolve


COLLECTION_FORMAT_SPLITTERS = {
    'csv': comma_split,
    'ssv': space_split,
    'tsv': tab_split,

# Path: lepo/apidef/parameter/base.py
# NO_VALUE = object()
# 
# class BaseParameter:
#     def __init__(self, data, api=None):
#         self.data = data
#         self.api = api
# 
#     def __repr__(self):
#         return f'<{self.__class__.__name__} ({self.data!r})>'
# 
#     @property
#     def location(self):
#         return self.data['in']
# 
#     @property
#     def required(self):
#         return bool(self.data.get('required'))
# 
#     @property
#     def items(self):
#         return self.data.get('items')
# 
#     def cast(self, api, value):  # pragma: no cover
#         raise NotImplementedError('Subclasses must implement cast')
# 
#     def get_value(self, request, view_kwargs):  # pragma: no cover
#         """
#         :type request: WSGIRequest
#         :type view_kwargs: dict
#         """
#         raise NotImplementedError('Subclasses must implement get_value')
# 
# class BaseTopParameter(BaseParameter):
#     """
#     Top-level Parameter, such as in an operation
#     """
# 
#     def __init__(self, data, api=None, operation=None):
#         super().__init__(data, api=api)
#         self.operation = operation
# 
#     @property
#     def name(self):
#         return self.data['name']
# 
#     @property
#     def in_body(self):
#         return self.location in ('formData', 'body')
# 
#     def get_value(self, request, view_kwargs):
#         raise InvalidParameterDefinition(f'unsupported `in` value {self.location!r} in {self!r}')  # pragma: no cover
# 
# Path: lepo/apidef/parameter/utils.py
# def comma_split(value):
#     return force_str(value).split(',')
# 
# def pipe_split(value):
#     return force_str(value).split('|')
# 
# def read_body(request, parameter=None):
#     if parameter:
#         if parameter.type == 'binary':
#             return request.body.read()
#     try:
#         if request.content_type == 'multipart/form-data':
#             # TODO: this definitely doesn't handle multiple values for the same key correctly
#             data = dict()
#             data.update(request.POST.items())
#             data.update(request.FILES.items())
#             return data
#         decoder = get_decoder(request.content_type)
#         if decoder:
#             return decoder(request.body, encoding=request.content_params.get('charset', 'UTF-8'))
#     except Exception as exc:
#         raise InvalidBodyContent(f'Unable to parse this body as {request.content_type}') from exc
#     raise NotImplementedError(f'No idea how to parse content-type {request.content_type}')  # pragma: no cover
# 
# def space_split(value):
#     return force_str(value).split(' ')
# 
# def tab_split(value):
#     return force_str(value).split('\t')
# 
# def validate_schema(schema, api, value):
#     schema = maybe_resolve(schema, resolve=api.resolve_reference)
#     jsonschema.validate(
#         value,
#         schema,
#         cls=LepoDraft4Validator,
#         resolver=api.resolver,
#     )
#     if 'discriminator' in schema:  # Swagger/OpenAPI 3 Polymorphism support
#         discriminator = schema['discriminator']
#         if isinstance(discriminator, dict):  # OpenAPI 3
#             type = value[discriminator['propertyName']]
#             if 'mapping' in discriminator:
#                 actual_type = discriminator['mapping'][type]
#             else:
#                 actual_type = f'#/components/schemas/{type}'
#         else:
#             type = value[discriminator]
#             actual_type = f'#/definitions/{type}'
#         schema = api.resolve_reference(actual_type)
#         jsonschema.validate(
#             value,
#             schema,
#             cls=LepoDraft4Validator,
#             resolver=api.resolver,
#         )
#     return value
# 
# Path: lepo/excs.py
# class InvalidBodyFormat(ValueError):
#     pass
# 
# Path: lepo/parameter_utils.py
# def cast_primitive_value(type, format, value):
#     if type == 'boolean':
#         return (force_str(value).lower() in ('1', 'yes', 'true'))
#     if type == 'integer' or format in ('integer', 'long'):
#         return int(value)
#     if type == 'number' or format in ('float', 'double'):
#         return float(value)
#     if format == 'byte':  # base64 encoded characters
#         return base64.b64decode(value)
#     if format == 'binary':  # any sequence of octets
#         return force_bytes(value)
#     if format == 'date':  # ISO8601 date
#         return iso8601.parse_date(value).date()
#     if format == 'dateTime':  # ISO8601 datetime
#         return iso8601.parse_date(value)
#     if type == 'string':
#         return force_str(value)
#     return value
# 
# Path: lepo/utils.py
# def maybe_resolve(object, resolve):
#     """
#     Call `resolve` on the `object`'s `$ref` value if it has one.
# 
#     :param object: An object.
#     :param resolve: A resolving function.
#     :return: An object, or some other object! :sparkles:
#     """
#     if isinstance(object, dict) and object.get('$ref'):
#         return resolve(object['$ref'])
#     return object


# Path: lepo/apidef/parameter/swagger.py
import jsonschema
from lepo.apidef.parameter.base import NO_VALUE, BaseParameter, BaseTopParameter
from lepo.apidef.parameter.utils import (
    comma_split,
    pipe_split,
    read_body,
    space_split,
    tab_split,
    validate_schema,
)
from lepo.excs import InvalidBodyFormat
from lepo.parameter_utils import cast_primitive_value
from lepo.utils import maybe_resolve



COLLECTION_FORMAT_SPLITTERS = {
    'csv': comma_split,
    'ssv': space_split,
    'tsv': tab_split,

    'pipes': pipe_split,