o
    !i&                     @   s   d dl mZ d dlmZ d dlmZmZmZ ddlm	Z	m
Z ddlmZ dd ZdddZdddZG dd deZG dd deZd	S )    OrderedDictwraps)requestcurrent_apphas_app_context   )Maskapply)unpackc                 C   s   t | tr|  S | S N)
isinstancetype)cls r   \/var/www/html/crm_dreinet/venv_linux/lib/python3.10/site-packages/flask_restx/marshalling.pymake
   s   
r   NFc                    s  t | ||||\}}|rddlm} g  g }	| D ]\}
}|
}t|tr/t| ||d}nXt|}t||}|rK|  |	rK| j	t
|	O  _	g }	|j|
| |d}|r fdd}|jp`|
}||| 	 |j|
| |d}|du s|||j|jkr}n	|j}||| qgq|	| r|du s|t ks|i krq ||f qt  |rt nt }|r|rt||fgn||i}|S |S )	  Takes raw data (in the form of a dict, list, object) and a dict of
    fields to output and filters the data based on those fields.

    :param data: the actual object(s) from which the fields are taken from
    :param fields: a dict of whose keys will make up the final serialized
                   response output
    :param envelope: optional key that will be used to envelop the serialized
                     response
    :param bool skip_none: optional key will be used to eliminate fields
                           which value is None or the field's key not
                           exist in data
    :param bool ordered: Wether or not to preserve order


    >>> from flask_restx import fields, marshal
    >>> data = { 'a': 100, 'b': 'foo', 'c': None }
    >>> mfields = { 'a': fields.Raw, 'c': fields.Raw, 'd': fields.Raw }

    >>> marshal(data, mfields)
    {'a': 100, 'c': None, 'd': None}

    >>> marshal(data, mfields, envelope='data')
    {'data': {'a': 100, 'c': None, 'd': None}}

    >>> marshal(data, mfields, skip_none=True)
    {'a': 100}

    >>> marshal(data, mfields, ordered=True)
    OrderedDict([('a', 100), ('c', None), ('d', None)])

    >>> marshal(data, mfields, envelope='data', ordered=True)
    OrderedDict([('data', OrderedDict([('a', 100), ('c', None), ('d', None)]))])

    >>> marshal(data, mfields, skip_none=True, ordered=True)
    OrderedDict([('a', 100)])

    r	   Wildcard	skip_noneorderedr   c                    s4   r|d u s|t  ks|i krd S  | |f d S r   )r   append)kvitemsr   r   r   _appendN   s   zmarshal.<locals>._appendTN)_marshalfieldsr   r   r   dictmarshalr   resetexcludesetoutputkey	containerformatdefaultr   r   tuple)datar"   enveloper   maskr   outhas_wildcardsr   keysdkeyvalr)   valuefieldis_wildcardr    r   r   r   r$      sR   &





r$   c                    s
  ddl m  |ptdd}td|rt|ddtttfrBfdd	D }|r>r:t||fgn||i}|d
fS dd
i fddfdd D }rfdd |D }rlt|nt	|}|rr{t||fgn||i}|d fS )r   r	   r   __mask__NresolvedTskipc                    s   g | ]
}t | d qS )r   )r$   ).0d)r"   r   r   r   r   
<listcomp>   s    z_marshal.<locals>.<listcomp>Fpresentc                    s2   t |}t| rdd< |j| d}| |fS )NTr@   r   )r   r   r(   )r)   r5   r7   r6   )r   r.   r2   r   r   r   __format_field   s
   
z _marshal.<locals>.__format_fieldc                 3   s<    | ]\}}t |tr|t|d fn ||V  qdS )r   N)r   r#   r$   r=   r   r   )rA   r.   r   r   r   r   	<genexpr>   s    
z_marshal.<locals>.<genexpr>c                 s   s6    | ]\}}|d ur|t  kr|i kr||fV  qd S r   r   rB   r   r   r   rC      s    ,)
r"   r   getattr
apply_maskr   listr-   r   r   r#   )r.   r"   r/   r   r0   r   r1   r   r   )r   rA   r.   r"   r2   r   r   r   r!   p   s.   'r!   c                   @   s$   e Zd ZdZ	dddZdd ZdS )	marshal_witha+  A decorator that apply marshalling to the return values of your methods.

    >>> from flask_restx import fields, marshal_with
    >>> mfields = { 'a': fields.Raw }
    >>> @marshal_with(mfields)
    ... def get():
    ...     return { 'a': 100, 'b': 'foo' }
    ...
    ...
    >>> get()
    OrderedDict([('a', 100)])

    >>> @marshal_with(mfields, envelope='data')
    ... def get():
    ...     return { 'a': 100, 'b': 'foo' }
    ...
    ...
    >>> get()
    OrderedDict([('data', OrderedDict([('a', 100)]))])

    >>> mfields = { 'a': fields.Raw, 'c': fields.Raw, 'd': fields.Raw }
    >>> @marshal_with(mfields, skip_none=True)
    ... def get():
    ...     return { 'a': 100, 'b': 'foo', 'c': None }
    ...
    ...
    >>> get()
    OrderedDict([('a', 100)])

    see :meth:`flask_restx.marshal`
    NFc                 C   s*   || _ || _|| _|| _t|dd| _dS )z
        :param fields: a dict of whose keys will make up the final
                       serialized response output
        :param envelope: optional key that will be used to envelop the serialized
                         response
        Tr;   N)r"   r/   r   r   r
   r0   )selfr"   r/   r   r0   r   r   r   r   __init__   s
   	zmarshal_with.__init__c                       t   fdd}|S )Nc                     s    | i |}j }t rtjd }tj|p|}t|tr6t	|\}}}t
|jjj|j||fS t
|jjj|jS )NRESTX_MASK_HEADER)r0   r   r   configr   headersgetr   r-   r   r$   r"   r/   r   r   )argskwargsrespr0   mask_headerr.   coderM   frH   r   r   wrapper   s*   

z&marshal_with.__call__.<locals>.wrapperr   rH   rU   rV   r   rT   r   __call__   s   zmarshal_with.__call__NFNF__name__
__module____qualname____doc__rI   rX   r   r   r   r   rG      s
    !
rG   c                   @   s    e Zd ZdZdd Zdd ZdS )marshal_with_fieldaP  
    A decorator that formats the return values of your methods with a single field.

    >>> from flask_restx import marshal_with_field, fields
    >>> @marshal_with_field(fields.List(fields.Integer))
    ... def get():
    ...     return ['1', 2, 3.0]
    ...
    >>> get()
    [1, 2, 3]

    see :meth:`flask_restx.marshal_with`
    c                 C   s    t |tr| | _dS || _dS )zP
        :param field: a single field with which to marshal the output.
        N)r   r   r7   )rH   r7   r   r   r   rI     s   

zmarshal_with_field.__init__c                    rJ   )Nc                     sD    | i |}t |trt|\}}}j|||fS j|S r   )r   r-   r   r7   r+   )rO   rP   rQ   r.   rS   rM   rT   r   r   rV   (  s
   
z,marshal_with_field.__call__.<locals>.wrapperr   rW   r   rT   r   rX   '  s   zmarshal_with_field.__call__NrZ   r   r   r   r   r_     s    	r_   rY   )collectionsr   	functoolsr   flaskr   r   r   r0   r
   r   rE   utilsr   r   r$   r!   objectrG   r_   r   r   r   r   <module>   s    

`QN