-
Notifications
You must be signed in to change notification settings - Fork 4
/
import.go
124 lines (106 loc) · 2.5 KB
/
import.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package golang
import (
"cmp"
"fmt"
"slices"
"strings"
"github.com/samber/lo"
"projectforge.dev/projectforge/app/util"
)
type ImportType string
const (
ImportTypeInternal ImportType = "internal"
ImportTypeExternal ImportType = "external"
ImportTypeApp ImportType = "app"
)
type Import struct {
Type ImportType
Value string
Alias string
}
func (i *Import) WithAlias(a string) *Import {
i.Alias = a
return i
}
func (i *Import) Render() string {
alias := ""
if i.Alias != "" {
alias = i.Alias + " "
}
return fmt.Sprintf("%s%q", alias, i.Value)
}
func (i *Import) Equals(x *Import) bool {
return x.Type == i.Type && x.Value == i.Value && x.Alias == i.Alias
}
func NewImport(t ImportType, v string) *Import {
return &Import{Type: t, Value: v}
}
type Imports []*Import
func (i Imports) Render(linebreak string) string {
if len(i) == 1 {
return fmt.Sprintf("import %s", i[0].Render())
}
ret := util.NewStringSlice([]string{"import ("})
ret.Push(i.toStrings("\t")...)
ret.Push(")")
return ret.Join(linebreak)
}
func (i Imports) RenderHTML(linebreak string) string {
if len(i) == 1 {
return fmt.Sprintf("{%% import %s %%}", i[0].Render())
}
ret := util.NewStringSlice([]string{"{%% import ("})
ret.Push(i.toStrings(" ")...)
ret.Push(") %%}")
return ret.Join(linebreak)
}
func (i Imports) toStrings(whitespace string) []string {
ret := &util.StringSlice{}
add := func(x []string, lf bool) {
if len(x) > 0 {
if lf {
ret.Push("")
}
lo.ForEach(x, func(item string, _ int) {
ret.Push(whitespace + item)
})
}
}
internal := i.renderByType(ImportTypeInternal)
external := i.renderByType(ImportTypeExternal)
app := i.renderByType(ImportTypeApp)
add(internal, false)
add(external, len(internal) > 0)
add(app, len(external) > 0 || len(internal) > 0)
return ret.Slice
}
func (i Imports) renderByType(t ImportType) []string {
ret := lo.FilterMap(i, func(x *Import, _ int) (string, bool) {
return x.Render(), x.Type == t
})
slices.SortFunc(ret, func(l string, r string) int {
if lIdx := strings.Index(l, " "); lIdx > -1 {
l = l[lIdx+1:]
}
if rIdx := strings.Index(r, " "); rIdx > -1 {
r = r[rIdx+1:]
}
return cmp.Compare(l, r)
})
return ret
}
func (i Imports) Add(imports ...*Import) Imports {
if i == nil {
return slices.Clone(imports)
}
ret := slices.Clone(i)
lo.ForEach(imports, func(imp *Import, _ int) {
hit := lo.ContainsBy(ret, func(x *Import) bool {
return x.Value == imp.Value
})
if !hit {
ret = append(ret, imp)
}
})
return ret
}