1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package fs
6
7import (
8	"time"
9)
10
11// FormatFileInfo returns a formatted version of info for human readability.
12// Implementations of [FileInfo] can call this from a String method.
13// The output for a file named "hello.go", 100 bytes, mode 0o644, created
14// January 1, 1970 at noon is
15//
16//	-rw-r--r-- 100 1970-01-01 12:00:00 hello.go
17func FormatFileInfo(info FileInfo) string {
18	name := info.Name()
19	b := make([]byte, 0, 40+len(name))
20	b = append(b, info.Mode().String()...)
21	b = append(b, ' ')
22
23	size := info.Size()
24	var usize uint64
25	if size >= 0 {
26		usize = uint64(size)
27	} else {
28		b = append(b, '-')
29		usize = uint64(-size)
30	}
31	var buf [20]byte
32	i := len(buf) - 1
33	for usize >= 10 {
34		q := usize / 10
35		buf[i] = byte('0' + usize - q*10)
36		i--
37		usize = q
38	}
39	buf[i] = byte('0' + usize)
40	b = append(b, buf[i:]...)
41	b = append(b, ' ')
42
43	b = append(b, info.ModTime().Format(time.DateTime)...)
44	b = append(b, ' ')
45
46	b = append(b, name...)
47	if info.IsDir() {
48		b = append(b, '/')
49	}
50
51	return string(b)
52}
53
54// FormatDirEntry returns a formatted version of dir for human readability.
55// Implementations of [DirEntry] can call this from a String method.
56// The outputs for a directory named subdir and a file named hello.go are:
57//
58//	d subdir/
59//	- hello.go
60func FormatDirEntry(dir DirEntry) string {
61	name := dir.Name()
62	b := make([]byte, 0, 5+len(name))
63
64	// The Type method does not return any permission bits,
65	// so strip them from the string.
66	mode := dir.Type().String()
67	mode = mode[:len(mode)-9]
68
69	b = append(b, mode...)
70	b = append(b, ' ')
71	b = append(b, name...)
72	if dir.IsDir() {
73		b = append(b, '/')
74	}
75	return string(b)
76}
77