Skip to content

Commit d2f6c0f

Browse files
committed
Add schema
0 parents  commit d2f6c0f

File tree

9 files changed

+693
-0
lines changed

9 files changed

+693
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.idea

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/NubeIO/lib-schema-go
2+
3+
go 1.18

schema/common.go

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package schema
2+
3+
type UUID struct {
4+
Type string `json:"type" default:"string"`
5+
Title string `json:"title" default:"UUID"`
6+
ReadOnly bool `json:"readOnly" default:"true"`
7+
}
8+
9+
type AddressUUID struct {
10+
Type string `json:"type" default:"string"`
11+
Title string `json:"title" default:"Address UUID"`
12+
Min int `json:"minLength" default:"1"`
13+
Max int `json:"maxLength" default:"100"`
14+
Default string `json:"default" default:""`
15+
ReadOnly bool `json:"readOnly" default:"false"`
16+
}
17+
18+
type Name struct {
19+
Type string `json:"type" default:"string"`
20+
Title string `json:"title" default:"Name"`
21+
Min int `json:"minLength" default:"2"`
22+
Max int `json:"maxLength" default:"200"`
23+
ReadOnly bool `json:"readOnly" default:"false"`
24+
}
25+
26+
type Model struct {
27+
Type string `json:"type" default:"string"`
28+
Title string `json:"title" default:"Model"`
29+
Options []string `json:"enum" default:"[]"`
30+
EnumName []string `json:"enumNames" default:"[]"`
31+
Default string `json:"default" default:""`
32+
ReadOnly bool `json:"readOnly" default:"false"`
33+
}
34+
35+
type Username struct {
36+
Type string `json:"type" default:"string"`
37+
Title string `json:"title" default:"Username"`
38+
Min int `json:"minLength" default:"2"`
39+
Max int `json:"maxLength" default:"50"`
40+
Default string `json:"default" default:"admin"`
41+
ReadOnly bool `json:"readOnly" default:"false"`
42+
}
43+
44+
type Password struct {
45+
Type string `json:"type" default:"string"`
46+
Title string `json:"title" default:"Password"`
47+
ReadOnly bool `json:"readOnly" default:"false"`
48+
}
49+
50+
type Token struct {
51+
Type string `json:"type" default:"string"`
52+
Title string `json:"title" default:"Token"`
53+
Min int `json:"minLength" default:"0"`
54+
Max int `json:"maxLength" default:"200"`
55+
ReadOnly bool `json:"readOnly" default:"false"`
56+
}
57+
58+
type ExternalToken struct {
59+
Type string `json:"type" default:"string"`
60+
Title string `json:"title" default:"External Token"`
61+
Min int `json:"minLength" default:"0"`
62+
Max int `json:"maxLength" default:"200"`
63+
ReadOnly bool `json:"readOnly" default:"false"`
64+
}
65+
66+
type Description struct {
67+
Type string `json:"type" default:"string"`
68+
Title string `json:"title" default:"Description"`
69+
}
70+
71+
type Enable struct {
72+
Type string `json:"type" default:"boolean"`
73+
Title string `json:"title" default:"Enable"`
74+
Default bool `json:"default" default:"true"`
75+
ReadOnly bool `json:"readOnly" default:"false"`
76+
}
77+
78+
type HistoryEnable struct {
79+
Type string `json:"type" default:"boolean"`
80+
Title string `json:"title" default:"History Enable"`
81+
Default bool `json:"default" default:"false"`
82+
ReadOnly bool `json:"readOnly" default:"false"`
83+
}
84+
85+
type HistoryEnableDefaultTrue struct {
86+
Type string `json:"type" default:"boolean"`
87+
Title string `json:"title" default:"History Enable"`
88+
Default bool `json:"default" default:"true"`
89+
ReadOnly bool `json:"readOnly" default:"false"`
90+
}
91+
92+
type Product struct {
93+
Type string `json:"type" default:"string"`
94+
Title string `json:"title" default:"Product"`
95+
Options []string `json:"enum" default:"[\"RubixCompute\",\"RubixCompute5\",\"RubixComputeIO\",\"Edge28\",\"Nuc\",\"Server\"]"`
96+
EnumName []string `json:"enumNames" default:"[\"RubixCompute\",\"RubixCompute5\",\"RubixComputeIO\",\"Edge28\",\"Nuc\",\"Server\"]"`
97+
Help string `json:"help" default:"a nube product type or a general linux server"`
98+
ReadOnly bool `json:"readOnly" default:"false"`
99+
}
100+
101+
type Interface struct {
102+
Type string `json:"type" default:"string"`
103+
Title string `json:"title" default:"Network Interface"`
104+
Options []string `json:"enum" default:"[]"`
105+
Default string `json:"default" default:"eth0"`
106+
Help string `json:"help" default:"host network interface card, eg eth0"`
107+
ReadOnly bool `json:"readOnly" default:"false"`
108+
}
109+
110+
type Netmask struct {
111+
Type string `json:"type" default:"string"`
112+
Title string `json:"title" default:"Netmask"`
113+
Default string `json:"default" default:"255.255.255.0"`
114+
Help string `json:"help" default:"ip netmask address eg, 255.255.255.0"`
115+
ReadOnly bool `json:"readOnly" default:"false"`
116+
}
117+
118+
type SubNetMask struct {
119+
Type string `json:"type" default:"number"`
120+
Title string `json:"title" default:"Subnet Mask"`
121+
Min int `json:"minLength" default:"8"`
122+
Max int `json:"maxLength" default:"30"`
123+
Default int `json:"default" default:"24"`
124+
ReadOnly bool `json:"readOnly" default:"false"`
125+
}
126+
127+
type Gateway struct {
128+
Type string `json:"type" default:"string"`
129+
Title string `json:"title" default:"Gateway"`
130+
Help string `json:"help" default:"ip gateway address eg, 192.168.15.1"`
131+
ReadOnly bool `json:"readOnly" default:"false"`
132+
Default string `json:"default" default:"192.168.15.1"`
133+
}
134+
135+
type HTTPS struct {
136+
Type string `json:"type" default:"boolean"`
137+
Title string `json:"title" default:"Enable HTTPS"`
138+
ReadOnly bool `json:"readOnly" default:"false"`
139+
}
140+
141+
type Port struct {
142+
Type string `json:"type" default:"number"`
143+
Title string `json:"title" default:"Port"`
144+
Min int `json:"minLength" default:"2"`
145+
Max int `json:"maxLength" default:"65535"`
146+
Default int `json:"default" default:"1660"`
147+
Help string `json:"help" default:"ip port, eg port 1660 192.168.15.10:1660"`
148+
ReadOnly bool `json:"readOnly" default:"false"`
149+
}
150+
151+
type PluginName struct {
152+
Type string `json:"type" default:"string"`
153+
Title string `json:"title" default:"Plugin"`
154+
ReadOnly bool `json:"readOnly" default:"true"`
155+
}
156+
157+
type OptionOneOf struct {
158+
Const string `json:"const"`
159+
Title string `json:"title"`
160+
}
161+
162+
type OptionOneOfInt struct {
163+
Const int `json:"const"`
164+
Title string `json:"title"`
165+
}
166+
167+
type DeviceType struct {
168+
Type string `json:"type" default:"string"`
169+
Title string `json:"title" default:"Device Type"`
170+
Options []string `json:"enum" default:"[\"cloud\",\"edge-28\",\"rubix-compute\",\"rubix-compute-vpn\",\"rubix-compute-lorawan\",\"rubix-compute-lorawan-vpn\",\"rubix-compute-io\"]"`
171+
Default string `json:"default" default:"rubix-compute"`
172+
}

schema/defaults.go

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package schema
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"reflect"
7+
"strconv"
8+
"time"
9+
)
10+
11+
var (
12+
errInvalidType = errors.New("not a struct pointer")
13+
)
14+
15+
const (
16+
fieldName = "default"
17+
)
18+
19+
// Set initializes members in a struct referenced by a pointer.
20+
// Maps and slices are initialized by `make` and other primitive types are set with default values.
21+
// `ptr` should be a struct pointer
22+
func Set(ptr interface{}) error {
23+
if reflect.TypeOf(ptr).Kind() != reflect.Ptr {
24+
return errInvalidType
25+
}
26+
27+
v := reflect.ValueOf(ptr).Elem()
28+
t := v.Type()
29+
30+
if t.Kind() != reflect.Struct {
31+
return errInvalidType
32+
}
33+
34+
for i := 0; i < t.NumField(); i++ {
35+
if defaultVal := t.Field(i).Tag.Get(fieldName); defaultVal != "-" {
36+
if err := setField(v.Field(i), defaultVal); err != nil {
37+
return err
38+
}
39+
}
40+
}
41+
callSetter(ptr)
42+
return nil
43+
}
44+
45+
// MustSet function is a wrapper of Set function
46+
// It will call Set and panic if err not equals nil.
47+
func MustSet(ptr interface{}) {
48+
if err := Set(ptr); err != nil {
49+
panic(err)
50+
}
51+
}
52+
53+
func setField(field reflect.Value, defaultVal string) error {
54+
if !field.CanSet() {
55+
return nil
56+
}
57+
58+
if !shouldInitializeField(field, defaultVal) {
59+
return nil
60+
}
61+
62+
isInitial := isInitialValue(field)
63+
// fmt.Println(field.Kind(), defaultVal)
64+
if isInitial {
65+
switch field.Kind() {
66+
case reflect.Bool:
67+
if val, err := strconv.ParseBool(defaultVal); err == nil {
68+
field.Set(reflect.ValueOf(val).Convert(field.Type()))
69+
}
70+
case reflect.Int:
71+
if val, err := strconv.ParseInt(defaultVal, 0, strconv.IntSize); err == nil {
72+
field.Set(reflect.ValueOf(int(val)).Convert(field.Type()))
73+
}
74+
case reflect.Int8:
75+
if val, err := strconv.ParseInt(defaultVal, 0, 8); err == nil {
76+
field.Set(reflect.ValueOf(int8(val)).Convert(field.Type()))
77+
}
78+
case reflect.Int16:
79+
if val, err := strconv.ParseInt(defaultVal, 0, 16); err == nil {
80+
field.Set(reflect.ValueOf(int16(val)).Convert(field.Type()))
81+
}
82+
case reflect.Int32:
83+
if val, err := strconv.ParseInt(defaultVal, 0, 32); err == nil {
84+
field.Set(reflect.ValueOf(int32(val)).Convert(field.Type()))
85+
}
86+
case reflect.Int64:
87+
if val, err := time.ParseDuration(defaultVal); err == nil {
88+
field.Set(reflect.ValueOf(val).Convert(field.Type()))
89+
} else if val, err := strconv.ParseInt(defaultVal, 0, 64); err == nil {
90+
field.Set(reflect.ValueOf(val).Convert(field.Type()))
91+
}
92+
case reflect.Uint:
93+
if val, err := strconv.ParseUint(defaultVal, 0, strconv.IntSize); err == nil {
94+
field.Set(reflect.ValueOf(uint(val)).Convert(field.Type()))
95+
}
96+
case reflect.Uint8:
97+
if val, err := strconv.ParseUint(defaultVal, 0, 8); err == nil {
98+
field.Set(reflect.ValueOf(uint8(val)).Convert(field.Type()))
99+
}
100+
case reflect.Uint16:
101+
if val, err := strconv.ParseUint(defaultVal, 0, 16); err == nil {
102+
field.Set(reflect.ValueOf(uint16(val)).Convert(field.Type()))
103+
}
104+
case reflect.Uint32:
105+
if val, err := strconv.ParseUint(defaultVal, 0, 32); err == nil {
106+
field.Set(reflect.ValueOf(uint32(val)).Convert(field.Type()))
107+
}
108+
case reflect.Uint64:
109+
if val, err := strconv.ParseUint(defaultVal, 0, 64); err == nil {
110+
field.Set(reflect.ValueOf(val).Convert(field.Type()))
111+
}
112+
case reflect.Uintptr:
113+
if val, err := strconv.ParseUint(defaultVal, 0, strconv.IntSize); err == nil {
114+
field.Set(reflect.ValueOf(uintptr(val)).Convert(field.Type()))
115+
}
116+
case reflect.Float32:
117+
if val, err := strconv.ParseFloat(defaultVal, 32); err == nil {
118+
field.Set(reflect.ValueOf(float32(val)).Convert(field.Type()))
119+
}
120+
case reflect.Float64:
121+
if val, err := strconv.ParseFloat(defaultVal, 64); err == nil {
122+
field.Set(reflect.ValueOf(val).Convert(field.Type()))
123+
}
124+
case reflect.String:
125+
field.Set(reflect.ValueOf(defaultVal).Convert(field.Type()))
126+
127+
case reflect.Slice:
128+
ref := reflect.New(field.Type())
129+
ref.Elem().Set(reflect.MakeSlice(field.Type(), 0, 0))
130+
if defaultVal != "" && defaultVal != "[]" {
131+
if err := json.Unmarshal([]byte(defaultVal), ref.Interface()); err != nil {
132+
return err
133+
}
134+
}
135+
field.Set(ref.Elem().Convert(field.Type()))
136+
case reflect.Map:
137+
ref := reflect.New(field.Type())
138+
ref.Elem().Set(reflect.MakeMap(field.Type()))
139+
if defaultVal != "" && defaultVal != "{}" {
140+
if err := json.Unmarshal([]byte(defaultVal), ref.Interface()); err != nil {
141+
return err
142+
}
143+
}
144+
field.Set(ref.Elem().Convert(field.Type()))
145+
case reflect.Struct:
146+
if defaultVal != "" && defaultVal != "{}" {
147+
if err := json.Unmarshal([]byte(defaultVal), field.Addr().Interface()); err != nil {
148+
return err
149+
}
150+
}
151+
case reflect.Ptr:
152+
field.Set(reflect.New(field.Type().Elem()))
153+
}
154+
}
155+
156+
switch field.Kind() {
157+
case reflect.Ptr:
158+
if isInitial || field.Elem().Kind() == reflect.Struct {
159+
setField(field.Elem(), defaultVal)
160+
callSetter(field.Interface())
161+
}
162+
case reflect.Struct:
163+
if err := Set(field.Addr().Interface()); err != nil {
164+
return err
165+
}
166+
case reflect.Slice:
167+
for j := 0; j < field.Len(); j++ {
168+
if err := setField(field.Index(j), defaultVal); err != nil {
169+
return err
170+
}
171+
}
172+
}
173+
174+
return nil
175+
}
176+
177+
func isInitialValue(field reflect.Value) bool {
178+
return reflect.DeepEqual(reflect.Zero(field.Type()).Interface(), field.Interface())
179+
}
180+
181+
func shouldInitializeField(field reflect.Value, tag string) bool {
182+
switch field.Kind() {
183+
case reflect.Struct:
184+
return true
185+
case reflect.Ptr:
186+
if !field.IsNil() && field.Elem().Kind() == reflect.Struct {
187+
return true
188+
}
189+
case reflect.Slice:
190+
return field.Len() > 0 || tag != ""
191+
}
192+
193+
return tag != ""
194+
}

0 commit comments

Comments
 (0)