1package table 2 3import ( 4 "fmt" 5 "io" 6 "reflect" 7 "strconv" 8 "strings" 9 "time" 10 11 semver "github.com/cppforlife/go-semi-semantic/version" 12 "github.com/dustin/go-humanize" 13 "gopkg.in/yaml.v2" 14 15 boshuifmt "github.com/cloudfoundry/bosh-cli/ui/fmt" 16) 17 18func NewValueString(s string) ValueString { return ValueString{S: s} } 19 20func (t ValueString) String() string { return t.S } 21func (t ValueString) Value() Value { return t } 22 23func (t ValueString) Compare(other Value) int { 24 otherS := other.(ValueString).S 25 switch { 26 case t.S == otherS: 27 return 0 28 case t.S < otherS: 29 return -1 30 default: 31 return 1 32 } 33} 34 35func (t EmptyValue) String() string { return "" } 36func (t EmptyValue) Value() Value { return t } 37func (t EmptyValue) Compare(Value) int { return 0 } 38 39func NewValueStrings(s []string) ValueStrings { return ValueStrings{S: s} } 40 41func (t ValueStrings) String() string { return strings.Join(t.S, "\n") } 42func (t ValueStrings) Value() Value { return t } 43 44func (t ValueStrings) Compare(other Value) int { 45 otherS := other.(ValueStrings).S 46 switch { 47 case len(t.S) == len(otherS): 48 return 0 49 case len(t.S) < len(otherS): 50 return -1 51 default: 52 return 1 53 } 54} 55 56func NewValueInt(i int) ValueInt { return ValueInt{I: i} } 57 58func (t ValueInt) String() string { return strconv.Itoa(t.I) } 59func (t ValueInt) Value() Value { return t } 60 61func (t ValueInt) Compare(other Value) int { 62 otherI := other.(ValueInt).I 63 switch { 64 case t.I == otherI: 65 return 0 66 case t.I < otherI: 67 return -1 68 default: 69 return 1 70 } 71} 72 73func NewValueBytes(i uint64) ValueBytes { return ValueBytes{I: i} } 74func NewValueMegaBytes(i uint64) ValueBytes { return ValueBytes{I: i * 1024 * 1024} } 75 76func (t ValueBytes) String() string { return humanize.IBytes(t.I) } 77func (t ValueBytes) Value() Value { return t } 78 79func (t ValueBytes) Compare(other Value) int { 80 otherI := other.(ValueBytes).I 81 switch { 82 case t.I == otherI: 83 return 0 84 case t.I < otherI: 85 return -1 86 default: 87 return 1 88 } 89} 90 91func NewValueTime(t time.Time) ValueTime { return ValueTime{T: t} } 92 93func (t ValueTime) String() string { 94 if t.T.IsZero() { 95 return "" 96 } 97 return t.T.Format(boshuifmt.TimeFullFmt) 98} 99func (t ValueTime) Value() Value { return t } 100 101func (t ValueTime) Compare(other Value) int { 102 otherT := other.(ValueTime).T 103 switch { 104 case t.T.Equal(otherT): 105 return 0 106 case t.T.Before(otherT): 107 return -1 108 default: 109 return 1 110 } 111} 112 113func NewValueBool(b bool) ValueBool { return ValueBool{B: b} } 114 115func (t ValueBool) String() string { return fmt.Sprintf("%t", t.B) } 116func (t ValueBool) Value() Value { return t } 117 118func (t ValueBool) Compare(other Value) int { 119 otherB := other.(ValueBool).B 120 switch { 121 case t.B == otherB: 122 return 0 123 case t.B == false && otherB == true: 124 return -1 125 default: 126 return 1 127 } 128} 129 130func NewValueVersion(v semver.Version) ValueVersion { return ValueVersion{V: v} } 131 132func (t ValueVersion) String() string { return t.V.String() } 133func (t ValueVersion) Value() Value { return t } 134 135func (t ValueVersion) Compare(other Value) int { 136 return t.V.Compare(other.(ValueVersion).V) 137} 138 139func NewValueError(e error) ValueError { return ValueError{E: e} } 140 141func (t ValueError) String() string { 142 if t.E != nil { 143 return t.E.Error() 144 } 145 return "" 146} 147 148func NewValueInterface(i interface{}) ValueInterface { return ValueInterface{I: i} } 149 150func (t ValueInterface) String() string { 151 if t.I == nil { 152 return "" 153 } 154 155 val := reflect.ValueOf(t.I) 156 157 if val.Kind() == reflect.Map && val.Len() == 0 { 158 return "" 159 } else if val.Kind() == reflect.Slice && val.Len() == 0 { 160 return "" 161 } 162 163 bytes, err := yaml.Marshal(t.I) 164 if err != nil { 165 return fmt.Sprintf("<serialization error> : %#v", t.I) 166 } 167 168 return strings.TrimSpace(string(bytes)) 169} 170func (t ValueInterface) Value() Value { return t } 171func (t ValueInterface) Compare(other Value) int { panic("Never called") } 172 173func (t ValueError) Value() Value { return t } 174func (t ValueError) Compare(other Value) int { panic("Never called") } 175 176func (t ValueNone) String() string { return "" } 177func (t ValueNone) Value() Value { return t } 178func (t ValueNone) Compare(other Value) int { panic("Never called") } 179 180func NewValueFmt(v Value, error bool) ValueFmt { return ValueFmt{V: v, Error: error} } 181 182func (t ValueFmt) String() string { return t.V.String() } 183func (t ValueFmt) Value() Value { return t.V } 184func (t ValueFmt) Compare(other Value) int { panic("Never called") } 185 186func (t ValueFmt) Fprintf(w io.Writer, pattern string, rest ...interface{}) (int, error) { 187 if t.Func == nil { 188 return fmt.Fprintf(w, pattern, rest...) 189 } 190 return fmt.Fprintf(w, "%s", t.Func(pattern, rest...)) 191} 192 193func NewValueSuffix(v Value, s string) ValueSuffix { return ValueSuffix{V: v, Suffix: s} } 194 195func (t ValueSuffix) String() string { 196 str := t.V.String() 197 if len(str) > 0 { 198 return str + t.Suffix 199 } 200 201 return "" 202} 203 204func (t ValueSuffix) Value() Value { return t.V } 205func (t ValueSuffix) Compare(other Value) int { panic("Never called") } 206