-
Notifications
You must be signed in to change notification settings - Fork 24
/
attrs.go
91 lines (72 loc) · 2.45 KB
/
attrs.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
package gocal
import (
"fmt"
"time"
"github.com/apognu/gocal/parser"
)
// resolve() processes a line's value, taking duplicate rule into account to inform failure modes.
// It takes as parameters:
// - A Gocal and Line instance
// - A pointer to the resulting field in the in-process event
// - A resolver function that parse the raw string value into the desired output type
// - An optional post-processing function that can modify other event attributs, if necessary
func resolve[T comparable](gc *Gocal, l *Line, dst *T, resolve func(gc *Gocal, l *Line) (T, T, error), post func(gc *Gocal, out T)) error {
// Retrieve the parsed value for the field, as well as its default value
value, empty, err := resolve(gc, l)
if err != nil {
return err
}
// Apply duplicate attribute rule if the target attribute is not empty (note: would fail for empty string values)
if dst != nil && *dst != empty {
if gc.Duplicate.Mode == DuplicateModeFailStrict {
return NewDuplicateAttribute(l.Key, l.Value)
}
}
// If the value is empty or the duplicate mode allows further processing, set the value
if *dst == empty || gc.Duplicate.Mode == DuplicateModeKeepLast {
*dst = value
if post != nil && dst != nil {
post(gc, *dst)
}
}
return nil
}
func resolveString(gc *Gocal, l *Line) (string, string, error) {
return l.Value, "", nil
}
func resolveDate(gc *Gocal, l *Line) (*time.Time, *time.Time, error) {
d, err := parser.ParseTime(l.Value, l.Params, parser.TimeStart, false, gc.AllDayEventsTZ)
if err != nil {
return nil, nil, fmt.Errorf("could not parse: %s", err)
}
return d, nil, nil
}
func resolveDateEnd(gc *Gocal, l *Line) (*time.Time, *time.Time, error) {
d, err := parser.ParseTime(l.Value, l.Params, parser.TimeEnd, false, gc.AllDayEventsTZ)
if err != nil {
return nil, nil, fmt.Errorf("could not parse: %s", err)
}
return d, nil, nil
}
func resolveDuration(gc *Gocal, l *Line) (*time.Duration, *time.Duration, error) {
d, err := parser.ParseDuration(l.Value)
if err != nil {
return nil, nil, fmt.Errorf("could not parse: %s", err)
}
return d, nil, nil
}
func resolveOrganizer(gc *Gocal, l *Line) (*Organizer, *Organizer, error) {
o := Organizer{
Cn: l.Params["CN"],
DirectoryDn: l.Params["DIR"],
Value: l.Value,
}
return &o, nil, nil
}
func resolveGeo(gc *Gocal, l *Line) (*Geo, *Geo, error) {
lat, long, err := parser.ParseGeo(l.Value)
if err != nil {
return nil, nil, err
}
return &Geo{lat, long}, nil, nil
}