Adding in some basic boilerplate for groups service. --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change - [x] 🌻 Feature
126 lines
2.7 KiB
Go
126 lines
2.7 KiB
Go
package details
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/alcionai/corso/src/cli/print"
|
|
)
|
|
|
|
// DetailsModel describes what was stored in a Backup
|
|
type DetailsModel struct {
|
|
Entries []Entry `json:"entries"`
|
|
}
|
|
|
|
// Print writes the DetailModel Entries to StdOut, in the format
|
|
// requested by the caller.
|
|
func (dm DetailsModel) PrintEntries(ctx context.Context) {
|
|
printEntries(ctx, dm.Entries)
|
|
}
|
|
|
|
type infoer interface {
|
|
Entry | *Entry
|
|
// Need this here so we can access the infoType function without a type
|
|
// assertion. See https://stackoverflow.com/a/71378366 for more details.
|
|
infoType() ItemType
|
|
}
|
|
|
|
func printEntries[T infoer](ctx context.Context, entries []T) {
|
|
if print.DisplayJSONFormat() {
|
|
printJSON(ctx, entries)
|
|
} else {
|
|
printTable(ctx, entries)
|
|
}
|
|
}
|
|
|
|
func printTable[T infoer](ctx context.Context, entries []T) {
|
|
perType := map[ItemType][]print.Printable{}
|
|
|
|
for _, ent := range entries {
|
|
it := ent.infoType()
|
|
ps, ok := perType[it]
|
|
|
|
if !ok {
|
|
ps = []print.Printable{}
|
|
}
|
|
|
|
perType[it] = append(ps, print.Printable(ent))
|
|
}
|
|
|
|
for _, ps := range perType {
|
|
print.All(ctx, ps...)
|
|
}
|
|
}
|
|
|
|
func printJSON[T infoer](ctx context.Context, entries []T) {
|
|
ents := []print.Printable{}
|
|
|
|
for _, ent := range entries {
|
|
ents = append(ents, print.Printable(ent))
|
|
}
|
|
|
|
print.All(ctx, ents...)
|
|
}
|
|
|
|
// Paths returns the list of Paths for non-folder and non-meta items extracted
|
|
// from the Entries slice.
|
|
func (dm DetailsModel) Paths() []string {
|
|
r := make([]string, 0, len(dm.Entries))
|
|
|
|
for _, ent := range dm.Entries {
|
|
if ent.Folder != nil || ent.isMetaFile() {
|
|
continue
|
|
}
|
|
|
|
r = append(r, ent.RepoRef)
|
|
}
|
|
|
|
return r
|
|
}
|
|
|
|
// Items returns a slice of *ItemInfo that does not contain any FolderInfo
|
|
// entries. Required because not all folders in the details are valid resource
|
|
// paths, and we want to slice out metadata.
|
|
func (dm DetailsModel) Items() entrySet {
|
|
res := make([]*Entry, 0, len(dm.Entries))
|
|
|
|
for i := 0; i < len(dm.Entries); i++ {
|
|
ent := dm.Entries[i]
|
|
if ent.Folder != nil || ent.isMetaFile() {
|
|
continue
|
|
}
|
|
|
|
res = append(res, &ent)
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
// FilterMetaFiles returns a copy of the Details with all of the
|
|
// .meta files removed from the entries.
|
|
func (dm DetailsModel) FilterMetaFiles() DetailsModel {
|
|
d2 := DetailsModel{
|
|
Entries: []Entry{},
|
|
}
|
|
|
|
for _, ent := range dm.Entries {
|
|
if !ent.isMetaFile() {
|
|
d2.Entries = append(d2.Entries, ent)
|
|
}
|
|
}
|
|
|
|
return d2
|
|
}
|
|
|
|
// SumNonMetaFileSizes returns the total size of items excluding all the
|
|
// .meta files from the items.
|
|
func (dm DetailsModel) SumNonMetaFileSizes() int64 {
|
|
var size int64
|
|
|
|
// Items will provide only files and filter out folders
|
|
for _, ent := range dm.FilterMetaFiles().Items() {
|
|
size += ent.size()
|
|
}
|
|
|
|
return size
|
|
}
|