code: func (info *Info) BuildFromFilePath(root string) (err error) {
  	info.Name = filepath.Base(root)
  	info.Files = nil
  	err = filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
  		if err != nil {
  			return err
  		}
  		if fi.IsDir() {
  			// Directories are implicit in torrent files.
  			return nil
  		} else if path == root {
  			// The root is a file.
  			info.Length = fi.Size()
  			return nil
  		}
  		relPath, err := filepath.Rel(root, path)
  		if err != nil {
  			return fmt.Errorf("error getting relative path: %s", err)
  		}
  		info.Files = append(info.Files, FileInfo{
  			Path:   strings.Split(relPath, string(filepath.Separator)),
  			Length: fi.Size(),
  		})
  		return nil
  	})
  	if err != nil {
  		return
  	}
  	slices.Sort(info.Files, func(l, r FileInfo) bool {
  		return strings.Join(l.Path, "/") < strings.Join(r.Path, "/")
  	})
  	err = info.GeneratePieces(func(fi FileInfo) (io.ReadCloser, error) {
  		return os.Open(filepath.Join(root, strings.Join(fi.Path, string(filepath.Separator))))
  	})
  	if err != nil {
  		err = fmt.Errorf("error generating pieces: %s", err)
  	}
  	return
  }
docs: // This is a helper that sets Files and Pieces from a root path and its
  // children.