package liber import ( "os" "path/filepath" "strings" ) type FileStorage struct { Root string Nesting int } func NewFileStorage(root string, nesting int) *FileStorage { return &FileStorage{ Root: root, Nesting: nesting, } } // Path of the file corresponding to the given key, relative to the // root directory. func (s *FileStorage) Path(key string) string { var parts []string for i := 0; i < s.Nesting; i++ { if i >= len(key) { break } parts = append(parts, key[i:i+1]) } parts = append(parts, key) return filepath.Join(parts...) } // Create a new file for the given key. func (s *FileStorage) Create(path string) (*os.File, error) { p := filepath.Join(s.Root, path) if err := os.MkdirAll(filepath.Dir(p), 0700); err != nil { return nil, err } return os.Create(p) } // Open a file. func (s *FileStorage) Open(path string) (*os.File, error) { if strings.HasPrefix(path, "/") { return os.Open(path) } return os.Open(filepath.Join(s.Root, path)) } // Rename oldpath to newpath. func (s *FileStorage) Rename(oldpath, newpath string) error { if !strings.HasPrefix(oldpath, "/") { oldpath = filepath.Join(s.Root, oldpath) } if !strings.HasPrefix(newpath, "/") { newpath = filepath.Join(s.Root, newpath) } return os.Rename(oldpath, newpath) }