o
    !i^                     @   s   d dl Z d dlZd dlmZ d dlmZ ddlmZ e e	Z
edZG dd deZG d	d
 d
eZG dd deZdddZdS )    N)OrderedDict)isclass   )	RestErrorz\{|\}|\,|[\w_:\-\*]+c                   @      e Zd ZdZdS )	MaskErrorz#Raised when an error occurs on maskN__name__
__module____qualname____doc__ r   r   U/var/www/html/crm_dreinet/venv_linux/lib/python3.10/site-packages/flask_restx/mask.pyr          r   c                   @   r   )
ParseErrorz#Raised when the mask parsing failedNr   r   r   r   r   r      r   r   c                       sJ   e Zd ZdZd fdd	Zdd Zdd	 Zd
d Zdd Zdd Z	  Z
S )Maskz
    Hold a parsed mask.

    :param str|dict|Mask mask: A mask, parsed or not
    :param bool skip: If ``True``, missing fields won't appear in result
    NFc                    sv   || _ t|trtt|   | | d S t|ttfr+tt| j|fi | d S || _ tt| jdi | d S )Nr   )	skip
isinstancestrsuperr   __init__parsedictr   )selfmaskr   kwargs	__class__r   r   r   "   s   
zMask.__init__c                 C   s   |sdS |  |}| }d}g }t|D ]B}|dkr4||vr"tdt| jd||< || || }n |dkrC|s>td| }n|dkrP|dv rOtd	nd
||< |}q|r]tddS )a  
        Parse a fields mask.
        Expect something in the form::

            {field,nested{nested_field,another},last}

        External brackets are optionals so it can also be written::

            field,nested{nested_field,another},last

        All extras characters will be ignored.

        :param str mask: the mask string to parse
        :raises ParseError: when a mask is unparseable/invalid

        N{zUnexpected opening bracket)r   }zUnexpected closing bracket,)r    r   NzUnexpected commaTMissing closing bracket)cleanLEXERfindallr   r   r   appendpop)r   r   fieldspreviousstacktokenr   r   r   r   -   s4   



z
Mask.parsec                 C   s@   | dd }|d dkr|d dkrtd|dd }|S )	zRemove unnecessary characters
 r   r   r   r!   r   )replacestripr   )r   r   r   r   r   r"   \   s   z
Mask.cleanc                    s   ddl m} t|tttfr fdd|D S t||j|j|jfr'|	 S t
||jkr8|j|j|j dS ||jkrC|j dS t||jsSt|rWt||jrWtdt|ttfsft|drf|j} |S )	z
        Apply a fields mask to the data.

        :param data: The data or model to apply mask on
        :raises MaskError: when unable to apply the mask

        r   )r'   c                    s   g | ]}  |qS r   )apply).0dr   r   r   
<listcomp>r   s    zMask.apply.<locals>.<listcomp>)default	attributer   )r   zMask is inconsistent with model__dict__)r,   r'   r   listtuplesetNestedList	PolymorphclonetypeRawr5   r6   r   
issubclassr   r   r   hasattrr7   filter_data)r   datar'   r   r3   r   r0   f   s&   




z
Mask.applyc                 C   s   i }|   D ]=\}}|dkrqt|tr3||d}| jr"|du r"q|du r+d||< q||||< q| jr;||vr;q||d||< qd|  v r[|  D ]\}}||vrZ|||< qN|S )z
        Handle the data filtering given a parsed mask

        :param dict data: the raw data to filter
        :param list mask: a parsed mask to filter against
        :param bool skip: whether or not to skip missing fields

        *N)itemsr   r   getr   r0   keys)r   rD   outfieldcontentnestedkeyvaluer   r   r   rC      s(   	

zMask.filter_datac                 C   s   d ddd |  D S )Nz{{{0}}}r    c                 S   s0   g | ]\}}t |trd |t|fn|qS )r,   )r   r   joinr   )r1   kvr   r   r   r4      s    z Mask.__str__.<locals>.<listcomp>)formatrO   rF   r3   r   r   r   __str__   s   zMask.__str__)NF)r	   r
   r   r   r   r   r"   r0   rC   rS   __classcell__r   r   r   r   r      s    /
  r   Fc                 C   s   t ||| S )a  
    Apply a fields mask to the data.

    :param data: The data or model to apply mask on
    :param str|Mask mask: the mask (parsed or not) to apply on data
    :param bool skip: If rue, missing field won't appear in result
    :raises MaskError: when unable to apply the mask

    )r   r0   )rD   r   r   r   r   r   r0      s   
r0   )F)loggingrecollectionsr   inspectr   errorsr   	getLoggerr	   logcompiler#   r   r   r   r0   r   r   r   r   <module>   s    

 