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

import (
	"context"
	"fmt"
	"io"
	"io/fs"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"
)

// File is a virtualized, generalized file abstraction for interacting with archives.
type File struct {
	fs.FileInfo

	// The file header as used/provided by the archive format.
	// Typically, you do not need to set this field when creating
	// an archive.
	Header interface{}

	// The path of the file as it appears in the archive.
	// This is equivalent to Header.Name (for most Header
	// types). We require it to be speci
    
func nameOnDiskToNameInArchive(nameOnDisk, rootOnDisk, rootInArchive string) string {
	// These manipulations of rootInArchive could be done just once instead of on
	// every walked file since they don't rely on nameOnDisk which is the only
	// variable that changes during the walk, but combining all the logic into this
	// one function is easier to reason about and test. I suspect the performance
	// penalty is insignificant.
	if strings.HasSuffix(rootOnDisk, string(filepath.Separator)) {
		rootInArchive = trimTopDir(rootInArchive)
	} else if rootInArchive == "" {
		rootInArchive = filepath.Base(rootOnDisk)
	}
	if strings.HasSuffix(rootInArchive, "/") {
		rootInArchive += filepath.Base(rootOnDisk)
	}
	truncPath := strings.TrimPrefix(nameOnDisk, rootOnDisk)
	return path.Join(rootInArchive, filepath.ToSlash(truncPath))
}