toBufIOWith :: Buffer -> BufSize -> (ByteString -> IO ()) -> Builder -> IO ()
toBufIOWith buf !size io builder = loop firstWriter
  where
    firstWriter = runBuilder builder
    runIO len = bufferIO buf len io
    loop writer = do
        (len, signal) <- writer buf size
        case signal of
             Done -> runIO len
             More minSize next
               | size < minSize -> error "toBufIOWith: BufferFull: minSize"
               | otherwise      -> do
                   runIO len
                   loop next
             Chunk bs next -> do
                 runIO len
                 io bs
                 loop next
toBufIOWith :: Buffer -> BufSize -> (ByteString -> IO ()) -> Builder -> IO ()
toBufIOWith buf !size io builder = loop firstWriter
  where
    firstWriter = runBuilder builder
    runIO len = bufferIO buf len io
    loop writer = do
        (len, signal) <- writer buf size
        case signal of
             Done -> runIO len
             More minSize next
               | size < minSize -> error "toBufIOWith: BufferFull: minSize"
               | otherwise      -> do
                   runIO len
                   loop next
             Chunk bs next -> do
                 runIO len
                 io bs
                 loop next
toBufIOWith buf !size io builder = loop firstWriter
  where
    firstWriter = runBuilder builder
    runIO len = bufferIO buf len io
    loop writer = do
        (len, signal) <- writer buf size
        case signal of
             Done -> runIO len
             More minSize next
               | size < minSize -> error "toBufIOWith: BufferFull: minSize"
               | otherwise      -> do
                   runIO len
                   loop next
             Chunk bs next -> do
                 runIO len
                 io bs
                 loop next