from typing import Iterator
from typing import Optional


def _stream_lines(blob: bytes) -> Iterator[bytes]:
    """
    Split bytes into lines (newline (\\n) character) on demand.

    >>> iter = _stream_lines(b"foo\\nbar\\n")
    >>> next(iter)
    b'foo'
    >>> next(iter)
    b'bar'
    >>> next(iter)
    Traceback (most recent call last):
        ...
    StopIteration

    >>> iter = _stream_lines(b"\\x00")
    >>> next(iter)
    b'\\x00'

    :param blob: the bytes to split.
    :return: a generated list of lines.
    """

    start = 0

    def _index(needle: bytes) -> Optional[int]:
        try:
            return blob.index(needle, start)
        except ValueError:
            return None

    line_index = _index(b"\n")
    while line_index is not None:
        yield blob[start:line_index]
        start = line_index + 1
        line_index = _index(b"\n")

    # Deal with blobs that do not end in a newline.
    if start < len(blob):
        yield blob[start:]