github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/api/client/inspect/inspector.go (about) 1 package inspect 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "text/template" 9 ) 10 11 // Inspector defines an interface to implement to process elements 12 type Inspector interface { 13 Inspect(typedElement interface{}, rawElement []byte) error 14 Flush() error 15 } 16 17 // TemplateInspector uses a text template to inspect elements. 18 type TemplateInspector struct { 19 outputStream io.Writer 20 buffer *bytes.Buffer 21 tmpl *template.Template 22 } 23 24 // NewTemplateInspector creates a new inspector with a template. 25 func NewTemplateInspector(outputStream io.Writer, tmpl *template.Template) Inspector { 26 return &TemplateInspector{ 27 outputStream: outputStream, 28 buffer: new(bytes.Buffer), 29 tmpl: tmpl, 30 } 31 } 32 33 // Inspect executes the inspect template. 34 // It decodes the raw element into a map if the initial execution fails. 35 // This allows docker cli to parse inspect structs injected with Swarm fields. 36 func (i *TemplateInspector) Inspect(typedElement interface{}, rawElement []byte) error { 37 buffer := new(bytes.Buffer) 38 if err := i.tmpl.Execute(buffer, typedElement); err != nil { 39 if rawElement == nil { 40 return fmt.Errorf("Template parsing error: %v", err) 41 } 42 return i.tryRawInspectFallback(rawElement, err) 43 } 44 i.buffer.Write(buffer.Bytes()) 45 i.buffer.WriteByte('\n') 46 return nil 47 } 48 49 // Flush write the result of inspecting all elements into the output stream. 50 func (i *TemplateInspector) Flush() error { 51 if i.buffer.Len() == 0 { 52 _, err := io.WriteString(i.outputStream, "\n") 53 return err 54 } 55 _, err := io.Copy(i.outputStream, i.buffer) 56 return err 57 } 58 59 // IndentedInspector uses a buffer to stop the indented representation of an element. 60 type IndentedInspector struct { 61 outputStream io.Writer 62 elements []interface{} 63 } 64 65 // NewIndentedInspector generates a new IndentedInspector. 66 func NewIndentedInspector(outputStream io.Writer) Inspector { 67 return &IndentedInspector{ 68 outputStream: outputStream, 69 } 70 } 71 72 // Inspect writes the raw element with an indented json format. 73 func (i *IndentedInspector) Inspect(typedElement interface{}, _ []byte) error { 74 i.elements = append(i.elements, typedElement) 75 return nil 76 } 77 78 // Flush write the result of inspecting all elements into the output stream. 79 func (i *IndentedInspector) Flush() error { 80 if len(i.elements) == 0 { 81 _, err := io.WriteString(i.outputStream, "[]\n") 82 return err 83 } 84 85 buffer, err := json.MarshalIndent(i.elements, "", " ") 86 if err != nil { 87 return err 88 } 89 90 if _, err := io.Copy(i.outputStream, bytes.NewReader(buffer)); err != nil { 91 return err 92 } 93 _, err = io.WriteString(i.outputStream, "\n") 94 return err 95 }