pkg/formatter/formatter.go (39 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. // Package formatter contains the logic to // template the CLI output to a specific format package formatter import "io" // Formatter models the formatter actions type Formatter interface { // Format is used from the cmd, it receives the parent and the data to be // formatted. The path usually has an effect on how the data will end up // being represented. Format(path string, data interface{}) error // Name obtains the name of the Formatter Name() string } // New initializes a ChainFormatter defaulting to the // JSON Formatter if no known formatter is passed, else // It will use the mentioned formatter and use the JSON // Formatter to fallback when parsing the output fails. func New(o io.Writer, name string) *Chain { fallbackFormatter := NewChain(NewJSON(o)) if name == "text" { fallbackFormatter = NewChain( NewText(&TextConfig{Output: o}), ).Add(fallbackFormatter) } return fallbackFormatter } // Chainer implements the Single Chain of Responsibility // Pattern, to be able to chain off multiple Formatters type Chainer interface { Formatter // Add adds a the next ChainFormatter to the chain Add(Chainer) *Chain } // NewChain wraps a formatter into a Chain func NewChain(f Formatter) *Chain { return &Chain{formatter: f} } // Chain implements the Chain interface // // Allows the formatting responsibility to become a chain. // It will cascade when formatter.Format returns an error // and the next property contains another actionable chain // (next != nil). When the Format is handled without error // it will return immediately type Chain struct { next Chainer formatter Formatter } // Format wraps the Format method of Formatter going down the chain // when formatter.Format returns an error and the next property // contains another actionable chain (next != nil). When the Format // is handled without error it will return immediately func (f Chain) Format(path string, data interface{}) error { err := f.formatter.Format(path, data) if err == nil { return nil } if f.next != nil { return f.next.Format(path, data) } return err } // Add adds a the next ChainFormatter to the chain func (f *Chain) Add(next Chainer) *Chain { f.next = next return f } // Name obtains the name of the Formatter func (f *Chain) Name() string { return f.formatter.Name() }