# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/05_sets.ipynb.

# %% auto 0
__all__ = ['setchain', 'try2set', 'any2set', 'asset']

# %% ../nbs/05_sets.ipynb 6
#| export


# %% ../nbs/05_sets.ipynb 8
#| export


# %% ../nbs/05_sets.ipynb 10
#| export


# %% ../nbs/05_sets.ipynb 12
from nlit import __HASH__
from sigr import applyfns
from chck import isiter, islist, istuple, isset, isiter, isiternotstr

# %% ../nbs/05_sets.ipynb 14
from .atyp import P

# %% ../nbs/05_sets.ipynb 17
def setchain(x, funcs, *args: P.args, **kwargs: P.kwargs): 
    '''Applies a sequence of functions (`funcs`) to an initial value `x`, 
    optionally stopping when the typeguard function `isset` returns `True`.
    
    See Also
    --------
    sigr.applyfns
    ''' 
    return applyfns(x, funcs, *args, check=isset, **kwargs)

# %% ../nbs/05_sets.ipynb 19
def try2set(a) -> set:
    '''Attempts to convert `a` to a set. 
    If `a` is already a set, returns it directly; otherwise, tries to create a set from `a`.
    
    Parameters
    ----------
    a : Any
        The input object to convert to a set.
        
    Returns
    -------
    set
        A set created from `a` if possible; otherwise, returns `a` itself if it cannot be converted.
    '''
    if isset(a): return a
    try: return set([a]) if not isiternotstr(a) else set(a)
    except: return a

# %% ../nbs/05_sets.ipynb 21
def any2set(obj) -> set:
    '''Attempts to convert any object to a set, handling strings and non-iterable 
    objects by creating a set of length 1 with the object.
    
    Parameters
    ----------
    obj : Any
        The object to convert to a set.
        
    Returns
    -------
    set
        The resulting set.  
        
    Notes
    -----
    - If the object is a string, it will be converted to a set of length 1.
    - If `obj` is a string or not iterable, the set will contain `obj` as its only item.
    - If `obj` is iterable, it converts the iterable to a set, unless `obj` is already a set.
    '''
    if isinstance(obj, str): obj = set((obj, ))
    elif not isiter(obj): obj = set((obj, )) # not a string and not iterable

    elif any(c(obj) for c in (isiter, islist, istuple)) and not isset(obj):    
        obj = set(obj)
    elif hasattr(obj, __HASH__): obj = {obj, }
    else:
        try: obj = set(obj)
        except TypeError: obj = set()
    return obj if isset(obj) else set()

# %% ../nbs/05_sets.ipynb 23
def asset(a, *args, **kwargs) -> set:
    '''Converts an input to a set.
    
    Parameters
    ----------
    a : Any
        The input to convert.
    
    *args : Any
        Additional arguments for conversion and adjustment functions.
        
    **kwargs : Any
        Additional keyword arguments for conversion and adjustment functions.
        
    Returns
    -------
    set
        The resulting set.
    '''
    if isset(a): return a
    chain = (any2set, try2set, )
    return setchain(a, chain, *args, **kwargs)
