func (m *memoryFS) Create(_ context.Context, path string, options *WriterOptions) (io.WriteCloser, error) {
	if options == nil {
		options = &WriterOptions{}
	}
	return &writingFile{
		Buffer:  &bytes.Buffer{},
		path:    path,
		m:       m,
		options: options,
	}, nil
}
Create implements FS.  NB: Callers must close the io.WriteCloser to create the file.
package storage
import (
	"bytes"
	"context"
	"io"
	"io/ioutil"
	"strings"
	"sync"
	"time"
)
func NewMemoryFS() FS {
	return &memoryFS{
		data: make(map[string]*memFile),
	}
}
type memFile struct {
	data  []byte
	attrs Attributes
}
func (f *memFile) readCloser() io.ReadCloser {
	return ioutil.NopCloser(bytes.NewReader(f.data))
}
type memoryFS struct {
	sync.RWMutex
	data map[string]*memFile
}
func (m *memoryFS) Open(_ context.Context, path string, options *ReaderOptions) (*File, error) {
	m.RLock()
	f, ok := m.data[path]
	m.RUnlock()
	if ok {
		return &File{
			ReadCloser: f.readCloser(),
			Attributes: f.attrs,
		}, nil
	}
	return nil, &notExistError{
		Path: path,
	}
}
func (m *memoryFS) Attributes(ctx context.Context, path string, options *ReaderOptions) (*Attributes, error) {
	m.RLock()
	f, ok := m.data[path]
	m.RUnlock()
	if ok {
		attrs := f.attrs
		return &attrs, nil
	}
	return nil, &notExistError{
		Path: path,
	}
}
type writingFile struct {
	*bytes.Buffer
	path string
	m       *memoryFS
	options *WriterOptions
}
func (wf *writingFile) Close() error {
	if wf.options.Attributes.Size == 0 {
		wf.options.Attributes.Size = int64(wf.Buffer.Len())
	}
	wf.m.Lock()
	if wf.options.Attributes.ModTime.IsZero() {
		wf.options.Attributes.ModTime = time.Now()
	}
	wf.m.data[wf.path] = &memFile{
		data:  wf.Buffer.Bytes(),
		attrs: wf.options.Attributes,
	}
	wf.m.Unlock()
	return nil
}