Rewrite source blob into this one.

        If :attr:`user_project` is set on the bucket, bills the API request
        to that project.

        :type source: :class:`Blob`
        :param source: blob whose contents will be rewritten into this blob.

        :type token: str
        :param token: Optional. Token returned from an earlier, not-completed
                       call to rewrite the same source blob.  If passed,
                       result will include updated status, total bytes written.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: Optional. The client to use.  If not passed, falls back
                       to the ``client`` stored on the blob's bucket.

        :rtype: tuple
        :returns: ``(token, bytes_rewritten, total_bytes)``, where ``token``
                  is a rewrite token (``None`` if the rewrite is complete),
                  ``bytes_rewritten`` is the number of bytes rewritten so far,
                  and ``total_bytes`` is the total number of bytes to be
                  rewritten.

def rewrite(self, source, token=None, client=None):
        """Rewrite source blob into this one.

        If :attr:`user_project` is set on the bucket, bills the API request
        to that project.

        :type source: :class:`Blob`
        :param source: blob whose contents will be rewritten into this blob.

        :type token: str
        :param token: Optional. Token returned from an earlier, not-completed
                       call to rewrite the same source blob.  If passed,
                       result will include updated status, total bytes written.

        :type client: :class:`~google.cloud.storage.client.Client` or
                      ``NoneType``
        :param client: Optional. The client to use.  If not passed, falls back
                       to the ``client`` stored on the blob's bucket.

        :rtype: tuple
        :returns: ``(token, bytes_rewritten, total_bytes)``, where ``token``
                  is a rewrite token (``None`` if the rewrite is complete),
                  ``bytes_rewritten`` is the number of bytes rewritten so far,
                  and ``total_bytes`` is the total number of bytes to be
                  rewritten.
        """
        client = self._require_client(client)
        headers = _get_encryption_headers(self._encryption_key)
        headers.update(_get_encryption_headers(source._encryption_key, source=True))

        query_params = self._query_params
        if "generation" in query_params:
            del query_params["generation"]

        if token:
            query_params["rewriteToken"] = token

        if source.generation:
            query_params["sourceGeneration"] = source.generation

        if self.kms_key_name is not None:
            query_params["destinationKmsKeyName"] = self.kms_key_name

        api_response = client._connection.api_request(
            method="POST",
            path=source.path + "/rewriteTo" + self.path,
            query_params=query_params,
            data=self._properties,
            headers=headers,
            _target_object=self,
        )
        rewritten = int(api_response["totalBytesRewritten"])
        size = int(api_response["objectSize"])

        # The resource key is set if and only if the API response is
        # completely done. Additionally, there is no rewrite token to return
        # in this case.
        if api_response["done"]:
            self._set_properties(api_response["resource"])
            return None, rewritten, size

        return api_response["rewriteToken"], rewritten, size