@@ -6,141 +6,70 @@ package api
6
6
7
7
import (
8
8
"errors"
9
- "strconv "
9
+ "strings "
10
10
11
- "github.com/SwanHubX/SwanLab/core/pkg/pb"
12
- )
11
+ "google.golang.org/protobuf/types/known/structpb"
13
12
14
- // Some constants for the parser.
15
- const (
16
- minRangeLen = 2
13
+ "github.com/SwanHubX/SwanLab/core/pkg/pb"
17
14
)
18
15
19
16
// Parser provides methods to parse proto messages to JSON sent to the SwanLab Server.
20
17
type Parser struct {
21
18
}
22
19
23
- // convertRange will convert the YRange from a proto message (like ["0", "None"]) to a JSON-compatible format(like [0, null]).
24
- // We expect the input to be a slice of strings with 2 elements, any other length will return an empty slice.
25
- func (p * Parser ) convertRange (r []string ) []interface {} {
26
- var left , right interface {} = nil , nil
27
- // must be at least 2 elements
28
- if len (r ) != minRangeLen {
29
- return []interface {}{}
30
- }
31
- if val , err := strconv .Atoi (r [0 ]); err == nil {
32
- left = val
33
- }
34
- if val , err := strconv .Atoi (r [1 ]); err == nil {
35
- right = val
36
- }
37
- return []interface {}{left , right }
38
- }
39
-
40
- // validateColumnClass will validate the columnClass.
41
- func (p * Parser ) validateColumnClass (record * pb.ColumnRecord ) (string , error ) {
42
- var class string
43
- switch record .GetColumnClass () {
44
- case pb .ColumnRecord_COL_CUSTOM :
45
- class = "CUSTOM"
46
- case pb .ColumnRecord_COL_SYSTEM :
47
- class = "SYSTEM"
48
- default :
49
- return "" , errors .New ("invalid column class: " + record .GetColumnClass ().String ())
50
- }
51
- return class , nil
52
- }
53
-
54
- // validateColumnType will validate the columnType.
55
- func (p * Parser ) validateColumnType (record * pb.ColumnRecord ) (string , error ) {
56
- switch record .GetColumnType () {
57
- case pb .ColumnRecord_COL_FLOAT :
58
- return "FLOAT" , nil
59
- case pb .ColumnRecord_COL_IMAGE :
60
- return "IMAGE" , nil
61
- case pb .ColumnRecord_COL_AUDIO :
62
- return "AUDIO" , nil
63
- case pb .ColumnRecord_COL_TEXT :
64
- return "TEXT" , nil
65
- case pb .ColumnRecord_COL_OBJECT3D :
66
- return "OBJECT3D" , nil
67
- case pb .ColumnRecord_COL_MOLECULE :
68
- return "MOLECULE" , nil
69
- case pb .ColumnRecord_COL_ECHARTS :
70
- return "ECHARTS" , nil
71
- default :
72
- return "" , errors .New ("invalid column type: " + record .GetColumnType ().String ())
73
- }
74
- }
75
-
76
- // validateSectionType will validate the sectionType.
77
- func (p * Parser ) validateSectionType (record * pb.ColumnRecord ) (string , error ) {
78
- var sectionType string
79
- switch record .GetSectionType () {
80
- case pb .ColumnRecord_SEC_CUSTOM :
81
- sectionType = "CUSTOM"
82
- case pb .ColumnRecord_SEC_SYSTEM :
83
- sectionType = "SYSTEM"
84
- case pb .ColumnRecord_SEC_PINNED :
85
- sectionType = "PINNED"
86
- case pb .ColumnRecord_SEC_HIDDEN :
87
- sectionType = "HIDDEN"
88
- case pb .ColumnRecord_SEC_PUBLIC :
89
- sectionType = "PUBLIC"
90
- default :
91
- return "" , errors .New ("invalid section type: " + record .GetSectionType ().String ())
92
- }
93
- return sectionType , nil
94
- }
95
-
20
+ // ColumnDTO represents the data transfer object for a column record.
21
+ // We use RESTFul naming conventions for the fields.
96
22
type ColumnDTO struct {
97
- Class string `json:"class"`
98
- Type string `json:"type"`
99
- Key string `json:"key"`
100
- Name string `json:"name,omitempty"`
101
- Error interface {} `json:"error,omitempty"`
102
- SectionName string `json:"section_name,omitempty"`
103
- SectionType string `json:"section_type,omitempty"`
23
+ Class string `json:"class"`
24
+ Type string `json:"type"`
25
+ Key string `json:"key"`
26
+ Name string `json:"name,omitempty"`
27
+ // e.g. {data_class: '', excepted: ''}
28
+ Error * structpb.Struct `json:"error,omitempty"`
29
+ SectionName string `json:"section_name,omitempty"`
30
+ SectionType string `json:"section_type,omitempty"`
104
31
// allow [0, 100] or [0, null] for y_range
105
- YRange []interface {} `json:"y_range,omitempty"`
106
- ChartIndex string `json:"chart_index,omitempty"`
107
- ChartName string `json:"chart_name,omitempty"`
108
- MetricName string `json:"metric_name,omitempty"`
109
- MetricColor []string `json:"metric_color,omitempty"`
32
+ YRange []* int64 `json:"y_range,omitempty"`
33
+ ChartIndex string `json:"chart_index,omitempty"`
34
+ ChartName string `json:"chart_name,omitempty"`
35
+ MetricName string `json:"metric_name,omitempty"`
36
+ MetricColor []string `json:"metric_color,omitempty"`
110
37
}
111
38
112
- // ParseColumnRecord parses a ColumnRecord proto message into a map[string]interface{} for JSON serialization .
39
+ // ParseColumnRecord parses a ColumnRecord proto message into ColumnDTO .
113
40
// Attention: y_range should be serialized to [0, null] in JSON, not ["0", "None"].
114
41
func (p * Parser ) ParseColumnRecord (record * pb.ColumnRecord ) (ColumnDTO , error ) {
115
42
// 1. parse the y_range, if error, yRange will be nil
116
- yRange := p .convertRange (record .GetChartYRange ())
43
+ var yRange []* int64
44
+ if record .GetChartYRange () != nil {
45
+ yRange = []* int64 {
46
+ //nolint:protogetter // We need pointers to represent null during JSON serialization.
47
+ record .GetChartYRange ().Minval ,
48
+ //nolint:protogetter // We need pointers to represent null during JSON serialization.s
49
+ record .GetChartYRange ().Maxval ,
50
+ }
51
+ }
117
52
// 2. parse the enum type
118
53
// 2.1 column class
119
- class , err := p .validateColumnClass (record )
120
- if err != nil {
121
- return ColumnDTO {}, err
122
- }
54
+ columnClass := strings .TrimPrefix (record .GetColumnClass ().String (), "COL_CLASS_" )
123
55
// 2.2 column type
124
- columnType , err := p .validateColumnType (record )
125
- if err != nil {
126
- return ColumnDTO {}, err
56
+ if record .GetColumnType () == pb .ColumnRecord_COL_UNKNOWN {
57
+ return ColumnDTO {}, errors .New ("column type is unknown" )
127
58
}
59
+ columnType := strings .TrimPrefix (record .GetColumnType ().String (), "COL_" )
128
60
// 2.3 section type
129
- sectionType , err := p .validateSectionType (record )
130
- if err != nil {
131
- return ColumnDTO {}, err
132
- }
61
+ sectionType := strings .TrimPrefix (record .GetSectionType ().String (), "SEC_" )
133
62
// 4. check if the key is empty, if so, return an error
134
63
key := record .GetColumnKey ()
135
64
if key == "" {
136
65
return ColumnDTO {}, errors .New ("column key cannot be EMPTY" )
137
66
}
138
67
// 5. check the metric color length, if it is not empty, it must be 2 elements
139
- if len (record .GetMetricColor ()) > 0 && len (record .GetMetricColor ()) != 2 {
68
+ if record . GetMetricColor () != nil && len (record .GetMetricColor ()) > 0 && len (record .GetMetricColor ()) != 2 {
140
69
return ColumnDTO {}, errors .New ("metric color must be empty or have exactly 2 elements" )
141
70
}
142
71
return ColumnDTO {
143
- Class : class ,
72
+ Class : columnClass ,
144
73
Type : columnType ,
145
74
Key : record .GetColumnKey (),
146
75
Name : record .GetColumnName (),
0 commit comments