-
Notifications
You must be signed in to change notification settings - Fork 17.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
io/fs: add FormatFileInfo and FormatDirEntry functions
For #54451 Change-Id: I3214066f77b1398ac1f2786ea035c83f32f0a826 Reviewed-on: https://go-review.googlesource.com/c/go/+/489555 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Joseph Tsai <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]>
- Loading branch information
1 parent
630ef2e
commit 72ba919
Showing
3 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pkg io/fs, func FormatDirEntry(DirEntry) string #54451 | ||
pkg io/fs, func FormatFileInfo(FileInfo) string #54451 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Copyright 2023 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package fs | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
// FormatFileInfo returns a formatted version of info for human readability. | ||
// Implementations of FileInfo can call this from a String method. | ||
// The output for a file named "hello.go", 100 bytes, mode 0o644, created | ||
// January 1, 1970 at noon is | ||
// | ||
// -rw-r--r-- 100 1970-01-01 12:00:00 hello.go | ||
func FormatFileInfo(info FileInfo) string { | ||
name := info.Name() | ||
b := make([]byte, 0, 40+len(name)) | ||
b = append(b, info.Mode().String()...) | ||
b = append(b, ' ') | ||
|
||
size := info.Size() | ||
var usize uint64 | ||
if size >= 0 { | ||
usize = uint64(size) | ||
} else { | ||
b = append(b, '-') | ||
usize = uint64(-size) | ||
} | ||
var buf [20]byte | ||
i := len(buf) - 1 | ||
for usize >= 10 { | ||
q := usize / 10 | ||
buf[i] = byte('0' + usize - q*10) | ||
i-- | ||
usize = q | ||
} | ||
buf[i] = byte('0' + usize) | ||
b = append(b, buf[i:]...) | ||
b = append(b, ' ') | ||
|
||
b = append(b, info.ModTime().Format(time.DateTime)...) | ||
b = append(b, ' ') | ||
|
||
b = append(b, name...) | ||
if info.IsDir() { | ||
b = append(b, '/') | ||
} | ||
|
||
return string(b) | ||
} | ||
|
||
// FormatDirEntry returns a formatted version of dir for human readability. | ||
// Implementations of DirEntry can call this from a String method. | ||
// The outputs for a directory named subdir and a file named hello.go are: | ||
// | ||
// d subdir/ | ||
// - hello.go | ||
func FormatDirEntry(dir DirEntry) string { | ||
name := dir.Name() | ||
b := make([]byte, 0, 5+len(name)) | ||
|
||
// The Type method does not return any permission bits, | ||
// so strip them from the string. | ||
mode := dir.Type().String() | ||
mode = mode[:len(mode)-9] | ||
|
||
b = append(b, mode...) | ||
b = append(b, ' ') | ||
b = append(b, name...) | ||
if dir.IsDir() { | ||
b = append(b, '/') | ||
} | ||
return string(b) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// Copyright 2023 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package fs_test | ||
|
||
import ( | ||
. "io/fs" | ||
"testing" | ||
"time" | ||
) | ||
|
||
// formatTest implements FileInfo to test FormatFileInfo, | ||
// and implements DirEntry to test FormatDirEntry. | ||
type formatTest struct { | ||
name string | ||
size int64 | ||
mode FileMode | ||
modTime time.Time | ||
isDir bool | ||
} | ||
|
||
func (fs *formatTest) Name() string { | ||
return fs.name | ||
} | ||
|
||
func (fs *formatTest) Size() int64 { | ||
return fs.size | ||
} | ||
|
||
func (fs *formatTest) Mode() FileMode { | ||
return fs.mode | ||
} | ||
|
||
func (fs *formatTest) ModTime() time.Time { | ||
return fs.modTime | ||
} | ||
|
||
func (fs *formatTest) IsDir() bool { | ||
return fs.isDir | ||
} | ||
|
||
func (fs *formatTest) Sys() any { | ||
return nil | ||
} | ||
|
||
func (fs *formatTest) Type() FileMode { | ||
return fs.mode.Type() | ||
} | ||
|
||
func (fs *formatTest) Info() (FileInfo, error) { | ||
return fs, nil | ||
} | ||
|
||
var formatTests = []struct { | ||
input formatTest | ||
wantFileInfo string | ||
wantDirEntry string | ||
}{ | ||
{ | ||
formatTest{ | ||
name: "hello.go", | ||
size: 100, | ||
mode: 0o644, | ||
modTime: time.Date(1970, time.January, 1, 12, 0, 0, 0, time.UTC), | ||
isDir: false, | ||
}, | ||
"-rw-r--r-- 100 1970-01-01 12:00:00 hello.go", | ||
"- hello.go", | ||
}, | ||
{ | ||
formatTest{ | ||
name: "home/gopher", | ||
size: 0, | ||
mode: ModeDir | 0o755, | ||
modTime: time.Date(1970, time.January, 1, 12, 0, 0, 0, time.UTC), | ||
isDir: true, | ||
}, | ||
"drwxr-xr-x 0 1970-01-01 12:00:00 home/gopher/", | ||
"d home/gopher/", | ||
}, | ||
{ | ||
formatTest{ | ||
name: "big", | ||
size: 0x7fffffffffffffff, | ||
mode: ModeIrregular | 0o644, | ||
modTime: time.Date(1970, time.January, 1, 12, 0, 0, 0, time.UTC), | ||
isDir: false, | ||
}, | ||
"?rw-r--r-- 9223372036854775807 1970-01-01 12:00:00 big", | ||
"? big", | ||
}, | ||
{ | ||
formatTest{ | ||
name: "small", | ||
size: -0x8000000000000000, | ||
mode: ModeSocket | ModeSetuid | 0o644, | ||
modTime: time.Date(1970, time.January, 1, 12, 0, 0, 0, time.UTC), | ||
isDir: false, | ||
}, | ||
"Surw-r--r-- -9223372036854775808 1970-01-01 12:00:00 small", | ||
"S small", | ||
}, | ||
} | ||
|
||
func TestFormatFileInfo(t *testing.T) { | ||
for i, test := range formatTests { | ||
got := FormatFileInfo(&test.input) | ||
if got != test.wantFileInfo { | ||
t.Errorf("%d: FormatFileInfo(%#v) = %q, want %q", i, test.input, got, test.wantFileInfo) | ||
} | ||
} | ||
} | ||
|
||
func TestFormatDirEntry(t *testing.T) { | ||
for i, test := range formatTests { | ||
got := FormatDirEntry(&test.input) | ||
if got != test.wantDirEntry { | ||
t.Errorf("%d: FormatDirEntry(%#v) = %q, want %q", i, test.input, got, test.wantDirEntry) | ||
} | ||
} | ||
|
||
} |