blob: 5b68d327587400219a0612dc365dd4718f52452d [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package random
import (
"encoding/json"
"fmt"
"github.com/mitchellh/mapstructure"
)
// serializableRules is a slice of rules that can be marshalled to JSON in an HCL format
type serializableRules []Rule
// MarshalJSON in an HCL-friendly way
func (r serializableRules) MarshalJSON() (b []byte, err error) {
// Example:
// [
// {
// "testrule": [
// {
// "string": "teststring",
// "int": 123
// }
// ]
// },
// {
// "charset": [
// {
// "charset": "abcde",
// "min-chars": 2
// }
// ]
// }
// ]
data := []map[string][]map[string]interface{}{} // Totally not confusing at all
for _, rule := range r {
ruleData := map[string]interface{}{}
err = mapstructure.Decode(rule, &ruleData)
if err != nil {
return nil, fmt.Errorf("unable to decode rule: %w", err)
}
ruleMap := map[string][]map[string]interface{}{
rule.Type(): {
ruleData,
},
}
data = append(data, ruleMap)
}
b, err = json.Marshal(data)
return b, err
}
func (r *serializableRules) UnmarshalJSON(data []byte) (err error) {
mapData := []map[string]interface{}{}
err = json.Unmarshal(data, &mapData)
if err != nil {
return err
}
rules, err := parseRules(defaultRegistry, mapData)
if err != nil {
return err
}
*r = rules
return nil
}
type runes []rune
func (r runes) Len() int { return len(r) }
func (r runes) Less(i, j int) bool { return r[i] < r[j] }
func (r runes) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
// MarshalJSON converts the runes to a string for smaller JSON and easier readability
func (r runes) MarshalJSON() (b []byte, err error) {
return json.Marshal(string(r))
}
// UnmarshalJSON converts a string to []rune
func (r *runes) UnmarshalJSON(data []byte) (err error) {
var str string
err = json.Unmarshal(data, &str)
if err != nil {
return err
}
*r = []rune(str)
return nil
}