import re


def camel_to_snake_case(name):
    name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
    name = re.sub('__([A-Z])', r'_\1', name)
    name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name)
    return name.lower()


def format_enum(v):
    return v.value if type(v) is not str else v


def replacer(s, newstring, index, nofail=False):
    # raise an error if index is outside of the string
    if not nofail and index not in range(len(s)):
        raise ValueError('index outside given string')

    # if not erroring, but the index is still not in the correct range..
    if index < 0:  # add it to the beginning
        return newstring + s
    if index > len(s):  # add it to the end
        return s + newstring

    # insert the new string between 'slices' of the original
    return s[:index] + newstring + s[index + 1:]


def remove_extension_from_filename(filename: str) -> str:
    parts = filename.split('/')
    fn = parts[-1].split('.')[0]
    return '/'.join(parts[:-1] + [fn])
