o
    €Ï1  ã                   @   sl   d Z ddlmZ ddlmZ ddlmZ G dd„ deƒZG dd„ deƒZG d	d
„ d
eƒZG dd„ deƒZ	dS )zIterable peek utilities.é    )Úabsolute_import)Údivision)Úunicode_literalsc                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚPeekera  Peeks the first element from an iterable.

  The returned object is another iterable that is equivalent to the original.
  If the object is not iterable then the first item is the object itself.

  Example:
    iterable = Peeker(iterable)
    first_item = iterable.Peek()
    assert list(iterable)[0] == first_item

  Attributes:
    _iterable: The original iterable.
    _peek: The first item in the iterable, or the iterable itself if its not
      iterable.
    _peek_seen: _peek was already seen by the first next() call.
  c                 C   s   || _ |  ¡ | _d| _d S ©NF)Ú	_iterableÚ_PeekÚ_peekÚ
_peek_seen)ÚselfÚiterable© r   úC/tmp/google-cloud-sdk/lib/googlecloudsdk/core/util/peek_iterable.pyÚ__init__)   s   

zPeeker.__init__c                 C   ó   | S ©Nr   ©r   r   r   r   Ú__iter__.   ó   zPeeker.__iter__c                 C   sf   zt | jƒW S  ty   Y n ty   d| _Y dS w z| j d¡W S  ttttfy2   Y | jS w )z'Peeks the first item from the iterable.TNr   )	Únextr   Ú	TypeErrorÚStopIterationr
   ÚpopÚAttributeErrorÚ
IndexErrorÚKeyErrorr   r   r   r   r   1   s   þýzPeeker._Peekc                 C   ó   |   ¡ S ©zFor Python 2 compatibility.©Ú__next__r   r   r   r   r   C   ó   zPeeker.nextc                 C   sn   | j s	d| _ | jS zt| jƒW S  ty   Y nw z| j d¡W S  ty*   Y t	‚ ttttfy6   t	‚w )z&Returns the next item in the iterable.Tr   )
r
   r	   r   r   r   r   r   r   r   r   r   r   r   r   r   G   s    ÿýÿzPeeker.__next__c                 C   ó   | j S )z'Returns the first item in the iterable.)r	   r   r   r   r   ÚPeek[   ó   zPeeker.PeekN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r"   r   r   r   r   r      s    r   c                   @   s2   e Zd ZdZd
dd„Zedd„ ƒZedd„ ƒZd	S )ÚTapInjectorzTap item injector.Fc                 C   s   || _ || _d S r   )Ú_valueÚ_is_replacement)r   ÚvalueÚreplacer   r   r   r   c   s   
zTapInjector.__init__c                 C   r!   r   )r)   r   r   r   r   r+   g   r#   zTapInjector.valuec                 C   r!   r   )r*   r   r   r   r   Úis_replacementk   r#   zTapInjector.is_replacementN)F)r$   r%   r&   r'   r   Úpropertyr+   r-   r   r   r   r   r(   `   s    

r(   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚTapzA Tapper Tap object.c                 C   s   |}dS )aû  Called on each item as it is fetched.

    Args:
      item: The current item to be tapped.

    Returns:
      True: The item is retained in the iterable.
      False: The item is deleted from the iterable.
      None: The item is deleted from the iterable and the iteration stops.
      Injector(): Injector.value is injected into the iterable. If
        Injector.is_replacement then the item is deleted from the iterable,
        otherwise the item appears in the iterable after the injected value.
    Tr   )r   ÚitemÚ_r   r   r   r/   s   s   zTap.Tapc                 C   s   dS )zCalled after the last item.Nr   r   r   r   r   ÚDone„   s   zTap.DoneN)r$   r%   r&   r'   r/   r2   r   r   r   r   r/   p   s    r/   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚTappera¢  Taps an iterable by calling a method for each item and after the last item.

  The returned object is another iterable that is equivalent to the original.
  If the object is not iterable then the first item is the object itself.

  Tappers may be used when it is not efficient or possible to completely drain
  a resource generator before the resources are finally consumed. For example,
  a paged resource may return the first page of resources immediately but have a
  significant delay between subsequent pages. A tapper allows the first page to
  be examined and consumed without waiting for the next page. If the tapper is a
  filter then it can filter and display a page before waiting for the next page.

  Example:
    tap = Tap()
    iterable = Tapper(iterable, tap)
    # The next statement calls tap.Tap(item) for each item and
    # tap.Done() after the last item.
    list(iterable)

  Attributes:
    _iterable: The original iterable.
    _tap: The Tap object.
    _stop: If True then the object is not iterable and it has already been
      returned.
    _injected: True if the previous _call_on_each injected a new item.
    _injected_value: The value to return next.
  c                 C   s"   || _ || _d| _d| _d | _d S r   )r   Ú_tapÚ_stopÚ	_injectedÚ_injected_value)r   r   Útapr   r   r   r   ¦   s
   
zTapper.__init__c                 C   r   r   r   r   r   r   r   r   ­   r   zTapper.__iter__c              
   C   s¶   | j r	d| _ | jS zt| jƒW S  ty   Y n ty$   | j ¡  ‚ w z| j d¡W S  t	t
tfy8   Y n tyE   | j ¡  t‚w | jdu sN| jrU| j ¡  t‚d| _| jS )z(Returns the next item in self._iterable.Fr   NT)r6   r7   r   r   r   r   r4   r2   r   r   r   r   r5   r   r   r   r   Ú	_NextItem°   s0   
þ
þ
zTapper._NextItemc                 C   r   r   r   r   r   r   r   r   Ì   r    zTapper.nextc                 C   sX   	 |   ¡ }| j |¡}|du r| j ¡  t‚t|tƒr'|js$d| _|| _	|j
S |r+|S q)z;Gets the next item, calls _tap.Tap() on it, and returns it.TN)r9   r4   r/   r2   r   Ú
isinstancer(   r-   r6   r7   r+   )r   r0   Úinject_or_keepr   r   r   r   Ð   s   

ôzTapper.__next__N)	r$   r%   r&   r'   r   r   r9   r   r   r   r   r   r   r3   ‰   s    r3   N)
r'   Ú
__future__r   r   r   Úobjectr   r(   r/   r3   r   r   r   r   Ú<module>   s   I