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: file.go
    path of file: ./repos/tegola/cache/file
    
    the code of the file until where you have to start completion: package file

import (
	"errors"
	"io/ioutil"
	"os"
	"path/filepath"

	"github.com/go-spatial/tegola"
	"github.com/go-spatial/tegola/cache"
	"github.com/go-spatial/tegola/dict"
)

var (
	ErrMissingBasepath = errors.New("filecache: missing required param 'basepath'")
)

const CacheType = "file"

const (
	ConfigKeyBasepath = "basepath"
	ConfigKeyMaxZoom  = "max_zoom"
)

func init() {
	cache.Register(CacheType, New)
}

// New instantiates a Cache. The config expects the following params:
//
// 	basepath (string): a path to where the cache will be written
// 	max_zoom (int): max zoom to use the cache. beyond this zoom cache Set() calls will be ignored
//
func New(config dict.Dicter) (cache.Interface, error) {
	var err error

	// new filecache
	fc := Cache{}

	defaultMaxZoom := uint(tegola.MaxZ)
	fc.MaxZoom, err = config.Uint(ConfigKeyMaxZoom, &defaultMaxZoom)
	if err != nil {
		return nil, err
	}

	fc.Basepath, err = config.String(ConfigKeyBasepath, nil)
	if err != nil {
		return nil, ErrMissingBasepath
	}

	if fc.Basepath == "" {
		return nil, ErrMissingBasepath
	}

	
    
func (fc *Cache) Set(key *cache.Key, val []byte) error {
	var err error

	// check for maxzoom
	if key.Z > fc.MaxZoom {
		return nil
	}

	// the tmpPath uses the destPath with a simple "-tmp" suffix. we're going to do
	// a Rename at the end of this method and according to the os.Rename() docs:
	// "If newpath already exists and is not a directory, Rename replaces it.
	// OS-specific restrictions may apply when oldpath and newpath are in different directories"
	destPath := filepath.Join(fc.Basepath, key.String())
	tmpPath := destPath + "-tmp"

	// the key can have a directory syntax so we need to makeAll
	if err = os.MkdirAll(filepath.Dir(destPath), os.ModePerm); err != nil {
		return err
	}

	// create the file
	f, err := os.Create(tmpPath)
	if err != nil {
		return err
	}

	// copy the contents
	_, err = f.Write(val)
	if err != nil {
		// close the file, can't use 'defer f.Close()'' otherwise rename wont happen
		f.Close()
		return err
	}

	// close the file, can't use 'defer f.Close()'' otherwise rename wont happen
	if err = f.Close(); err != nil {
		return err
	}

	// move the temp file to the destination
	return os.Rename(tmpPath, destPath)
}