1// Copyright (c) 2017 Ernest Micklei
2//
3// MIT License
4//
5// Permission is hereby granted, free of charge, to any person obtaining
6// a copy of this software and associated documentation files (the
7// "Software"), to deal in the Software without restriction, including
8// without limitation the rights to use, copy, modify, merge, publish,
9// distribute, sublicense, and/or sell copies of the Software, and to
10// permit persons to whom the Software is furnished to do so, subject to
11// the following conditions:
12//
13// The above copyright notice and this permission notice shall be
14// included in all copies or substantial portions of the Software.
15//
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24package proto
25
26import "strings"
27import "bytes"
28
29type aligned struct {
30	source  string
31	left    bool
32	padding bool
33}
34
35var (
36	alignedEquals      = leftAligned(" = ")
37	alignedShortEquals = leftAligned("=")
38	alignedSpace       = leftAligned(" ")
39	alignedComma       = leftAligned(", ")
40	alignedEmpty       = leftAligned("")
41	alignedSemicolon   = leftAligned(";")
42)
43
44func leftAligned(src string) aligned  { return aligned{src, true, true} }
45func rightAligned(src string) aligned { return aligned{src, false, true} }
46func notAligned(src string) aligned   { return aligned{src, false, false} }
47
48func (a aligned) preferredWidth() int {
49	if !a.hasAlignment() {
50		return 0 // means do not force padding because of this source
51	}
52	return len(a.source)
53}
54
55func (a aligned) formatted(indentSeparator string, indentLevel, width int) string {
56	if !a.padding {
57		// if the source has newlines then make sure the correct indent level is applied
58		buf := new(bytes.Buffer)
59		for _, each := range a.source {
60			buf.WriteRune(each)
61			if '\n' == each {
62				buf.WriteString(strings.Repeat(indentSeparator, indentLevel))
63			}
64		}
65		return buf.String()
66	}
67	if a.left {
68		return a.source + strings.Repeat(" ", width-len(a.source))
69	}
70	return strings.Repeat(" ", width-len(a.source)) + a.source
71}
72
73func (a aligned) hasAlignment() bool { return a.left || a.padding }
74