pkg/bundle/fs/directory.go (75 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package fs import ( "errors" "io" "io/fs" "os" "sync" "time" ) type directory struct { sync.RWMutex name string perm os.FileMode modTime time.Time children map[string]interface{} } // Compile time type assertion var _ fs.ReadDirFile = (*directory)(nil) // ----------------------------------------------------------------------------- func (d *directory) Stat() (fs.FileInfo, error) { return &fileInfo{ name: d.name, size: 1, modTime: d.modTime, mode: d.perm | fs.ModeDir, }, nil } //nolint:revive // refactor use of byte func (d *directory) Read(b []byte) (int, error) { return 0, errors.New("is a directory") } func (d *directory) Close() error { return nil } func (d *directory) ReadDir(n int) ([]fs.DirEntry, error) { // Lock for read d.RLock() defer d.RUnlock() // Retrieve children entry count childrenNames := []string{} for entryName := range d.children { childrenNames = append(childrenNames, entryName) } // Apply read limit if n <= 0 { n = len(childrenNames) } // Iterate on children entities out := []fs.DirEntry{} for i := 0; i < len(childrenNames) && i < n; i++ { name := childrenNames[i] h := d.children[name] switch item := h.(type) { case *directory: out = append(out, &dirEntry{ fi: &fileInfo{ name: item.name, size: 1, mode: item.perm | os.ModeDir, }, }) case *file: out = append(out, &dirEntry{ fi: &fileInfo{ name: item.name, size: item.size, modTime: item.modTime, mode: item.mode, }, }) default: continue } } // Check directory entry exhaustion if n > len(childrenNames) { return out, io.EOF } // Check empty response if len(out) == 0 { return out, errors.New("directory has no entry") } // Return result return out, nil }