-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnaming.go
More file actions
101 lines (85 loc) · 2.4 KB
/
Copy pathnaming.go
File metadata and controls
101 lines (85 loc) · 2.4 KB
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
package morph
import (
"fmt"
"strings"
"text/template"
"unicode"
"unicode/utf8"
"github.com/seeruk/morph/plan"
"github.com/seeruk/morph/spec"
"github.com/seeruk/morph/types"
)
// NameInput is a type used to collect information used for templating a mapper function name.
type NameInput struct {
Source types.Type
Target types.Type
Signature spec.MapperSignature
RunHash string
}
type nameTemplateData struct {
Source nameType
Target nameType
Signature nameSignature
RunHash string
}
func nameTemplateDataFromInput(input NameInput) nameTemplateData {
return nameTemplateData{
Source: nameTypeFromType(input.Source),
Target: nameTypeFromType(input.Target),
Signature: nameSignatureFromType(input.Signature),
RunHash: input.RunHash,
}
}
// nameType is a basic representation of a type for use in name templates.
type nameType struct {
Type string
Package string
}
// nameTypeFromType returns a nameType from the given types.Type.
func nameTypeFromType(typ types.Type) nameType {
return nameType{
Type: typ.Name,
Package: uppercaseFirst(typ.Package.Name),
}
}
// nameSignature is a basic representation of a signature for use in name templates.
type nameSignature struct {
Accepts string
Returns string
}
func nameSignatureFromType(sig spec.MapperSignature) nameSignature {
return nameSignature{
Accepts: uppercaseFirst(sig.Accepts.String()),
Returns: uppercaseFirst(sig.Returns.String()),
}
}
// MapperName attempts to return a name for the given NameInput using Go's text/template library,
// with NameInput as the template data.
func MapperName(input NameInput, templ string) (string, error) {
temp := template.New(plan.TypeMapperKey(
plan.TypeRefFromType(input.Source),
plan.TypeRefFromType(input.Target),
input.Signature,
))
temp, err := temp.Parse(templ)
if err != nil {
return "", fmt.Errorf("failed to parse template: %w", err)
}
var sb strings.Builder
if err := temp.Execute(&sb, nameTemplateDataFromInput(input)); err != nil {
return "", fmt.Errorf("failed to execute template: %w", err)
}
return sb.String(), nil
}
// uppercaseFirst uppercases the first Unicode character in the string, leaving the rest of the
// string untouched.
func uppercaseFirst(s string) string {
if s == "" {
return s
}
r, size := utf8.DecodeRuneInString(s)
if r == utf8.RuneError && size == 0 {
return s
}
return string(unicode.ToUpper(r)) + s[size:]
}