def _semver_components(version):
    """Separates a semver into its components.

    I.e. separates `MAJOR.MINOR.PATCH-PRERELEASE+BUILD` into

    * the version core `MAJOR.MINOR.PATCH`
    * the optional `PRERELEASE` identifier, `None` if missing
    * the optional `BUILD` identifier, `None` if missing

    Returns:
      The tuple `(version, prerelease, build)`.
    """
    dash_pos = version.find("-")
    plus_pos = version.find("+")

    if dash_pos != -1:
        core_end = dash_pos
    elif plus_pos != -1:
        core_end = plus_pos
    else:
        core_end = len(version)

    if plus_pos != -1:
        prerelease_end = plus_pos
    else:
        prerelease_end = len(version)

    build_end = len(version)

    core = version[:core_end]

    if dash_pos != -1:
        prerelease = version[core_end + 1:prerelease_end]
    else:
        prerelease = None

    if plus_pos != -1:
        build = version[prerelease_end + 1:build_end]
    else:
        build = None

    return (core, prerelease, build)