importreimportstringfromtypingimportAnyfromtypingimportListfromtypingimportMatchfromtypingimportTuplestop_words={"","Decimal","Dict","Enum","False","List","Meta","None","Optional","QName","True","Type","Tuple","Union","and","as","assert","bool","break","class","continue","def","del","dict","elif","else","except","field","finally","float","for","from","global","if","import","in","int","is","lambda","list","nonlocal","not","object",# py36 specific"or","pass","raise","return","self","str","try","while","with","yield",}is_reserved=stop_words.__contains__defprefix(value:str,sep:str=":")->str:"""Return the first part of the string before the separator."""returnsplit(value,sep)[0]defsuffix(value:str,sep:str=":")->str:"""Return the last part of the string after the separator."""returnsplit(value,sep)[1]defsplit(value:str,sep:str=":")->Tuple:""" Separate the given string with the given separator and return a tuple of the prefix and suffix. If the separator isn't present in the string return None as prefix. """left,_,right=value.partition(sep)return(left,right)ifrightelse(None,left)
[docs]defcapitalize(value:str,**kwargs:Any)->str:"""Capitalize the given string."""returnvalue[0].upper()+value[1:]
deforiginal_case(value:str,**kwargs:Any)->str:"""Return the input string without any modifications."""returnvalue
[docs]defpascal_case(value:str,**kwargs:Any)->str:"""Convert the given string to pascal case."""return"".join(map(str.title,split_words(value)))
[docs]defcamel_case(value:str,**kwargs:Any)->str:"""Convert the given string to camel case."""result="".join(map(str.title,split_words(value)))returnresult[0].lower()+result[1:]
[docs]defmixed_case(value:str,**kwargs:Any)->str:"""Convert the given string to mixed case."""return"".join(split_words(value))
[docs]defmixed_pascal_case(value:str,**kwargs:Any)->str:"""Convert the given string to mixed pascal case."""returncapitalize(mixed_case(value))
[docs]defmixed_snake_case(value:str,**kwargs:Any)->str:"""Convert the given string to mixed snake case."""return"_".join(split_words(value))
[docs]defsnake_case(value:str,**kwargs:Any)->str:"""Convert the given string to snake case."""return"_".join(map(str.lower,split_words(value)))
defscreaming_snake_case(value:str,**kwargs:Any)->str:"""Convert the given string to screaming snake case."""returnsnake_case(value,**kwargs).upper()
[docs]defkebab_case(value:str,**kwargs:Any)->str:"""Convert the given string to kebab case."""return"-".join(split_words(value))
defsplit_words(value:str)->List[str]:"""Split a string on new capital letters and not alphanumeric characters."""words:List[str]=[]buffer:List[str]=[]previous=Nonedefflush():ifbuffer:words.append("".join(buffer))buffer.clear()forcharinvalue:tp=classify(char)iftp==StringType.OTHER:flush()elifnotpreviousortp==previous:buffer.append(char)eliftp==StringType.UPPERandprevious!=StringType.UPPER:flush()buffer.append(char)else:buffer.append(char)previous=tpflush()returnwordsclassStringType:UPPER=1LOWER=2NUMERIC=3OTHER=4defclassify(character:str)->int:"""String classifier."""code_point=ord(character)if64<code_point<91:returnStringType.UPPERif96<code_point<123:returnStringType.LOWERif47<code_point<58:returnStringType.NUMERICreturnStringType.OTHERESCAPE=re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')ESCAPE_DCT={"\\":"\\\\",'"':'\\"',"\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t",}foriinrange(0x20):ESCAPE_DCT.setdefault(chr(i),f"\\u{i:04x}")defescape_string(value:str)->str:""" Escape a string for code generation. Source: json.encoder.py_encode_basestring """defreplace(match:Match)->str:returnESCAPE_DCT[match.group(0)]returnESCAPE.sub(replace,value)__alnum_ascii__=set(string.digits+string.ascii_letters)defalnum(value:str)->str:"""Return a lower case version of the string only with ascii alphanumerical characters."""return"".join(filter(__alnum_ascii__.__contains__,value)).lower()