-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmetadata.go
125 lines (95 loc) · 2.08 KB
/
metadata.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
125
package hype
import (
"encoding/json"
"fmt"
"strings"
"github.com/gopherguides/hype/atomx"
"github.com/markbates/syncx"
)
type Metadata struct {
Element *Element
syncx.Map[string, string]
}
func (md *Metadata) MarshalJSON() ([]byte, error) {
if md == nil || md.Element == nil {
return nil, ErrIsNil("metadata")
}
el := md.Element
el.RLock()
defer el.RUnlock()
m, err := el.JSONMap()
if err != nil {
return nil, err
}
m["type"] = toType(md)
m["data"] = md.Map.Map()
return json.MarshalIndent(m, "", " ")
}
func (md *Metadata) IsEmptyNode() bool {
return false
}
func (md *Metadata) Children() Nodes {
if md == nil || md.Element == nil {
return nil
}
return md.Element.Children()
}
func (md *Metadata) PostParse(p *Parser, d *Document, err error) error {
if md == nil {
return fmt.Errorf("metadata is nil")
}
if d == nil {
return fmt.Errorf("document is nil")
}
heads := ByAtom(d.Nodes, atomx.Head)
if len(heads) == 0 {
return nil
}
hd := heads[0]
head, ok := hd.(*Element)
if !ok {
return fmt.Errorf("head is not an element: %T", hd)
}
keys := md.Map.Keys()
for _, key := range keys {
el := NewEl(atomx.Meta, head)
val, _ := md.Map.Get(key)
el.Set(key, val)
head.Nodes = append(head.Nodes, el)
}
return nil
}
func NewMetadata(el *Element) (*Metadata, error) {
if el == nil {
return nil, ErrIsNil("element")
}
m := &Metadata{
Element: el,
Map: syncx.Map[string, string]{},
}
body := m.Children().String()
for _, line := range strings.Split(body, "\n") {
line = strings.TrimSpace(line)
if len(line) == 0 {
continue
}
parts := strings.SplitN(line, ":", 2)
if len(parts) != 2 {
return nil, el.WrapErr(fmt.Errorf("invalid metadata line: %s", line))
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
if err := m.Set(key, value); err != nil {
return nil, el.WrapErr(err)
}
}
m.Element.Nodes = Nodes{}
return m, nil
}
func NewMetadataNodes(p *Parser, el *Element) (Nodes, error) {
md, err := NewMetadata(el)
if err != nil {
return nil, err
}
return Nodes{md}, nil
}