You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: compressor.go
    path of file: ./repos/gotosocial/vendor/codeberg.org/gruf/go-store/v2/storage
    
    the code of the file until where you have to start completion: package storage

import (
	"bytes"
	"io"
	"sync"

	"codeberg.org/gruf/go-iotools"

	"github.com/klauspost/compress/gzip"
	"github.com/klauspost/compress/snappy"
	"github.com/klauspost/compress/zlib"
)

// Compressor defines a means of compressing/decompressing values going into a key-value store
type Compressor interface {
	// Reader returns a new decompressing io.ReadCloser based on supplied (compressed) io.Reader
	Reader(io.ReadCloser) (io.ReadCloser, error)

	// Writer returns a new compressing io.WriteCloser based on supplied (uncompressed) io.Writer
	Writer(io.WriteCloser) (io.WriteCloser, error)
}

type gzipCompressor struct {
	rpool sync.Pool
	wpool sync.Pool
}

// GZipCompressor returns a
    
func GZipCompressorLevel(level int) Compressor {
	// GZip readers immediately check for valid
	// header data on allocation / reset, so we
	// need a set of valid header data so we can
	// iniitialize reader instances in mempool.
	hdr := bytes.NewBuffer(nil)

	// Init writer to ensure valid level provided
	gw, err := gzip.NewWriterLevel(hdr, level)
	if err != nil {
		panic(err)
	}

	// Write empty data to ensure gzip
	// header data is in byte buffer.
	_, _ = gw.Write([]byte{})
	_ = gw.Close()

	return &gzipCompressor{
		rpool: sync.Pool{
			New: func() any {
				hdr := bytes.NewReader(hdr.Bytes())
				gr, _ := gzip.NewReader(hdr)
				return gr
			},
		},
		wpool: sync.Pool{
			New: func() any {
				gw, _ := gzip.NewWriterLevel(nil, level)
				return gw
			},
		},
	}
}