# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/03_utils.ipynb.

# %% auto 0
__all__ = ['psyn', 'nsyn', 'zsyn', 'any2signint', 'num2signint', 'str2signint', 'numstr2signint', 'tosignint', 'matchsign',
           'toint', 'tochr', 'tosym', 'tosyn', 'toset', 'topow', 'tosign', 'totuple']

# %% ../nbs/03_utils.ipynb 3
from numbers import Number
from typing import Any, Optional

# %% ../nbs/03_utils.ipynb 4
from .types import NumStr, SignInt, SignChr, SignSym, NumStrQ, SignIntQ
from .guard import ispos, isneg, isstr, isnum, isnumstr
from .sign import sign, P, Z, N

# %% ../nbs/03_utils.ipynb 5
from bflag import BoolCall, tern2x

# %% ../nbs/03_utils.ipynb 7
def psyn(s: str) -> bool: return P.issyn(s)
def nsyn(s: str) -> bool: return N.issyn(s)
def zsyn(s: str) -> bool: return Z.issyn(s)

def any2signint(val: Any, posfn: Optional[BoolCall] = ispos, negfn: Optional[BoolCall] = isneg) -> SignInt: 
    return tern2x(val, posfn, negfn, P.int, N.int, Z.int)

def num2signint(s: Number) -> SignInt: return any2signint(s, ispos, isneg)
def str2signint(s: str) -> SignInt:
    try: return num2signint(int(s))
    except: return any2signint(s, psyn, nsyn)

def numstr2signint(s: NumStrQ) -> SignInt: return str2signint(s) if isstr(s) else num2signint(s) if isnum(s) else Z.int

def tosignint(s: Any) -> SignIntQ: return numstr2signint(s) if isnumstr(s) else None
def matchsign(val: Any, pos: Any = P.int, neg: Any = N.int, nil: Any = Z.int, default: Any = None) -> Any:
    match tosignint(val):
        case  1: return pos
        case -1: return neg
        case  0: return nil
        case  _: return default

def toint(s: NumStr) -> SignInt: return matchsign(s, P.int, N.int, Z.int)
def tochr(s: NumStr) -> SignChr: return matchsign(s, P.chr, N.chr, Z.chr)
def tosym(s: NumStr) -> SignSym: return matchsign(s, P.sym, N.sym, Z.sym)
def tosyn(s: NumStr) -> set: return matchsign(s, P.syn, N.syn, Z.syn)
def toset(s: NumStr) -> set: return matchsign(s, P.set, N.set, Z.set)
def topow(base: int, expo: int, sign: NumStrQ = None) -> Number: return base ** (expo * tosignint(sign or expo))

def tosign(s: NumStr) -> Optional[sign]: return matchsign(s, P, N, Z)
def totuple(s: NumStr) -> tuple: return tuple(tosign(s))
