
    hKj*                        d Z dZddlZddlZddlZddlZddlmZmZm	Z	 ddl
Z
ej                  Zddeg dg dfdee   dee   deg ef   d	e	e
j                  eeef   fd
Zddee   d	efdZ	 ddeeg ef      d	efdZ	 dde	ee
j                  ef   d	ee   fdZ	 dde	ee
j                  ef   d	eej                     fdZy)z
Implementation of UUID v7 per the October 2021 draft update
to RFC4122 from 2005:
https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format

Stephen Simmons, v0.1.0, 2021-12-27
)uuid7uuid7strtime_nscheck_timing_precisionuuid_to_datetime    N)CallableOptionalUnion)r   r   r   r   nsas_type	time_funcreturnc           
         | 
 |       } |}n|}t        |       } | dk(  rdx}x}x}}	d}
nd}t        | |      \  }}t        |dz  |      \  }}t        |dz  |      \  }}|dz  }||d   k(  r&||d   k(  r||d	   k(  r|d
   dk  r|d
xx   dz  cc<   n	|||df|dd d|d
   z  }	t        j                  d      }
|dk(  r"|dd|dd|dd|	dd|
j	                          	S t         j                  |
d      }|dz  |dz  z   |dz  z   |	dz  z   |z   }|dk(  r|S |dk(  r|dS |dk(  r|j                  dd      S t        j                  |      S )u-  
    UUID v7, following the proposed extension to RFC4122 described in
    https://www.ietf.org/id/draft-peabody-dispatch-new-uuid-format-02.html.
    All representations (string, byte array, int) sort chronologically,
    with a potential time resolution of 50ns (if the system clock
    supports this).

    Parameters
    ----------

    ns      - Optional integer with the whole number of nanoseconds
                since Unix epoch, to set the "as of" timestamp.
                As a special case, uuid7(ns=0) returns the zero UUID.

    as_type - Optional string to return the UUID in a different format.
                A uuid.UUID (version 7, variant 0x10) is returned unless
                this is one of 'str', 'int', 'hex' or 'bytes'.

    time_func - Set the time function, which must return integer
                nanoseconds since the Unix epoch, midnight on 1-Jan-1970.
                Defaults to time.time_ns(). This is exposed because
                time.time_ns() may have a low resolution on Windows.

    _last and _last_as_of - Used internally to trigger incrementing a
                sequence counter when consecutive calls have the same time
                values. The values [t1, t2, t3, seq] are described below.

    Returns
    -------

    A UUID object, or if as_type is specified, a string, int or
    bytes of length 16.

    Implementation notes
    --------------------

    The 128 bits in the UUID are allocated as follows:
    - 36 bits of whole seconds
    - 24 bits of fractional seconds, giving approx 50ns resolution
    - 14 bits of sequential counter, if called repeatedly in same time tick
    - 48 bits of randomness
    plus, at locations defined by RFC4122, 4 bits for the
    uuid version (0b111) and 2 bits for the uuid variant (0b10).

             0                   1                   2                   3
             0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    t1      |                 unixts (secs since epoch)                     |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    t2/t3   |unixts |  frac secs (12 bits)  |  ver  |  frac secs (12 bits)  |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    t4/rand |var|       seq (14 bits)       |          rand (16 bits)       |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    rand    |                          rand (32 bits)                       |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    Indicative timings:
    - uuid.uuid4()            2.4us
    - uuid7()                 3.7us
    - uuid7(as_type='int')    1.6us
    - uuid7(as_type='str')    2.5us

    Examples
    --------

    >>> uuid7()
    UUID('061cb26a-54b8-7a52-8000-2124e7041024')

    >>> uuid7(0)
    UUID('00000000-0000-0000-0000-00000000000')

    >>> for fmt in ('bytes', 'hex', 'int', 'str', 'uuid', None):
    ...     print(fmt, repr(uuid7(as_type=fmt)))
    bytes b'¸þ|9 	jt³»'
    hex '061cb8fe0f0b7c3980011863b956b758'
    int 8124504378724980906989670469352026642
    str '061cb8fe-0f0b-7c39-8003-d44a7ee0bdf6'
    uuid UUID('061cb8fe-0f0b-7c39-8004-0489578299f6')
    None UUID('061cb8fe-0f0f-7df2-8000-afd57c2bf446')
    Nr   s         l     Ys       i p           ?  i      strz>08x-z>04xbig`   P   @   0   inthexz>032xbytes)r   )	r   divmodosurandomr   
from_bytesto_bytesuuidUUID)r   r   r   _last_last_as_oflastt1t2t3t4randsixteen_secsrest1rest2_ruuid_ints                    f/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/uuid_extensions/uuid7.pyr   r      s   n 
z[W	QwR"r &2|,	E5B;5	Eu{L1A
g
 a=R47]rT!W} AwQ12r1oDGa  zz!} %T!Bt9AbYa4y$((*FFtU#AbR2X&"(3rRx@1DH%	E	5!"	G	  U++yyX&&    c                     t        | d      S )z9uuid7() as a string without creating a UUID object first.r   )r   )r   )r   s    r6   r   r      s    U##r7   timing_funcc                    dt         j                  fdt         j                  fdd fg}| |j                  d| f       g }|D ]  \  }}t        j                         }t	               }d}	 |j                   |              |dz  }t        j                         |z
  }|dkD  st        |      d	k\  rnG|t        |      z  }	||z  }
|j                  | d
|	dd|
dd|ddt        |      dd|dz  dd        dj                  |      S )aL  
    Message indicating the timing precision from various time/clock
    functions that might be used for UUIDv7 generation.

    This tests time.time_ns(), time.perf_counter_ns()
    and datetime.datetime.utcnow converted to ns.

    A user-supplied timing function may also be provided.
    It must return the number of ns since the Unix Epoch
    (midnight at 1-Jan-1970).

    Note that time.time_ns() updates every 200us under Linux
    and potentially as infrequently as every 5ms under Windows.

    Usage:
    >>> check_timing_precision()
    # Under Linux
    time.time_ns()           has a timing precision of   221ns rather than 221ns (1,000 distinct samples in 0.00s)
    time.perf_counter_ns()   has a timing precision of   215ns rather than 215ns (1,000 distinct samples in 0.00s)
    datetime.datetime.utcnow has a timing precision of 1,046ns rather than 679ns (1,000 distinct samples in 0.00s)
    # Under Windows
    time.time_ns()           has a timing precision of 4,950,500ns rather than   709ns (705,068 samples of which 101 are distinct, in 0.50s)
    time.perf_counter_ns()   has a timing precision of       823ns rather than   823ns (1,000 samples of which 1,000 are distinct, in 0.00s)
    datetime.datetime.utcnow has a timing precision of 5,882,365ns rather than 2,812ns (177,792 samples of which 85 are distinct, in 0.50s)
    ztime.time_ns()ztime.perf_counter_ns()zdatetime.datetime.utcnowc                  r    t        t        j                  j                         j                         dz        S )N ʚ;)r   datetimeutcnow	timestamp r7   r6   <lambda>z(check_timing_precision.<locals>.<lambda>   s*    S$$&002]B.Dr7   zuser-suppliedr   r   i ei  z has a timing precision of z0,.0fzns rather than zns (,z samples of which z are distinct, in r<   z0.2fzs)
)timer   perf_counter_nsappendsetaddlenjoin)r9   timing_funcslinesdescfn
started_nsvaluesctr
elapsed_nsprecision_nsideal_precision_nss              r6   r   r      sH   : 
4<<(	!4#7#78	# &D 	EL _k:;E b))+
JJrt1HC--/*<JK'3v;$+>  "CK/'#-f/U/C D&d3q' 2VQ!*}"<T!B"F	
 !$ 99Ur7   sc                 X   t        | t        j                        r| j                  }nl| sd}ngt        | t              rt        j                  | dd      }n>t	        t        |       j                  dd      d      }t        j                  |dd      }|d   d	z	  }|d
k(  rnt        j                  d|      }|d   dz	  dz  }|d   d	z  |d   dz	  z   }|d   dz  dz  |d   dz  dz  z   |d   dz  z   }t        |dz  d      \  }}	|dz  |z   }
|
S |ryt        t        |        d| d      )a\  
    Recover the timestamp from a UUIDv7, passed in
    as a string, integer or a UUID object.

    If the UUID is not a version 7 UUID, either raise a ValueError
    or return None, depending on suppress_error.

    Usage:
    >>> uuid_to_datetime("1eb22fe4-3f0c-62b1-a88c-8dc55231702f")
    datetime.datetime(2020, 11, 10, 2, 41, 42, 182162)
    s                   r   r   )length	byteorderr    )baser         z>IHHHHIr   r      r   r   i        r   r   r<   l        Nz is a version z1 UUID, not v7 so we cannot extract the timestamp.)
isinstancer&   r'   r    r   r%   r   replacestructunpackr!   
ValueError)rU   suppress_errorxint_uuiduuid_versionbits
whole_secsfrac_binaryfrac_nsr3   ns_since_epochs              r6   timestamp_nsrn      sV    !TYYGG	As	LL2L7s1v~~c2.R8LL"L>Q419Lq}}Y*Q2,1gltAw"}5
1g2%Q& R')Q& # 	
 K-7A
#m3g=	1vhn\N 3+ ,
 	
r7   c                     t        | |      }|y t        j                  j                  |dz  t        j                  j                        S )N)re   r<   )tz)rn   r=   fromtimestamptimezoneutc)rU   re   rm   s      r6   r   r     sN     "!NCN  ..]*  $$ / 
 	
r7   )N)T)__doc____all__r=   r"   rb   rD   typingr   r	   r
   r&   r   r   r   r'   r    r   r   r   rn   r   r@   r7   r6   <module>rw      s>    	   , ,  ,, !#*
M'M'c]M' C M' 499c3%&M'`$# $# $ 048(2s7+,88z -
S$))S !-
 c]-
d 
S$))S !
 h 
r7   