1package formatter
2
3import (
4	"fmt"
5	"strings"
6
7	"github.com/docker/docker/api/types"
8	units "github.com/docker/go-units"
9)
10
11const (
12	defaultVolumeQuietFormat = "{{.Name}}"
13	defaultVolumeTableFormat = "table {{.Driver}}\t{{.Name}}"
14
15	volumeNameHeader = "VOLUME NAME"
16	mountpointHeader = "MOUNTPOINT"
17	linksHeader      = "LINKS"
18	// Status header ?
19)
20
21// NewVolumeFormat returns a format for use with a volume Context
22func NewVolumeFormat(source string, quiet bool) Format {
23	switch source {
24	case TableFormatKey:
25		if quiet {
26			return defaultVolumeQuietFormat
27		}
28		return defaultVolumeTableFormat
29	case RawFormatKey:
30		if quiet {
31			return `name: {{.Name}}`
32		}
33		return `name: {{.Name}}\ndriver: {{.Driver}}\n`
34	}
35	return Format(source)
36}
37
38// VolumeWrite writes formatted volumes using the Context
39func VolumeWrite(ctx Context, volumes []*types.Volume) error {
40	render := func(format func(subContext SubContext) error) error {
41		for _, volume := range volumes {
42			if err := format(&volumeContext{v: *volume}); err != nil {
43				return err
44			}
45		}
46		return nil
47	}
48	return ctx.Write(newVolumeContext(), render)
49}
50
51type volumeContext struct {
52	HeaderContext
53	v types.Volume
54}
55
56func newVolumeContext() *volumeContext {
57	volumeCtx := volumeContext{}
58	volumeCtx.Header = SubHeaderContext{
59		"Name":       volumeNameHeader,
60		"Driver":     DriverHeader,
61		"Scope":      ScopeHeader,
62		"Mountpoint": mountpointHeader,
63		"Labels":     LabelsHeader,
64		"Links":      linksHeader,
65		"Size":       SizeHeader,
66	}
67	return &volumeCtx
68}
69
70func (c *volumeContext) MarshalJSON() ([]byte, error) {
71	return MarshalJSON(c)
72}
73
74func (c *volumeContext) Name() string {
75	return c.v.Name
76}
77
78func (c *volumeContext) Driver() string {
79	return c.v.Driver
80}
81
82func (c *volumeContext) Scope() string {
83	return c.v.Scope
84}
85
86func (c *volumeContext) Mountpoint() string {
87	return c.v.Mountpoint
88}
89
90func (c *volumeContext) Labels() string {
91	if c.v.Labels == nil {
92		return ""
93	}
94
95	var joinLabels []string
96	for k, v := range c.v.Labels {
97		joinLabels = append(joinLabels, fmt.Sprintf("%s=%s", k, v))
98	}
99	return strings.Join(joinLabels, ",")
100}
101
102func (c *volumeContext) Label(name string) string {
103	if c.v.Labels == nil {
104		return ""
105	}
106	return c.v.Labels[name]
107}
108
109func (c *volumeContext) Links() string {
110	if c.v.UsageData == nil {
111		return "N/A"
112	}
113	return fmt.Sprintf("%d", c.v.UsageData.RefCount)
114}
115
116func (c *volumeContext) Size() string {
117	if c.v.UsageData == nil {
118		return "N/A"
119	}
120	return units.HumanSize(float64(c.v.UsageData.Size))
121}
122