package main import ( "encoding/json" "fmt" "strings" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" ) type NamespacesConfig struct { Namespaces Namespaces `json:"namespaces"` } type Namespaces map[string]Namespace type Namespace struct { Name string `json:"-"` LocationConstraints LocationConstraints `json:"location_constraints"` CopiesNumbers map[string][]uint32 `json:"copies_numbers"` } type LocationConstraints map[string]netmap.PlacementPolicy func (c *Namespaces) UnmarshalJSON(data []byte) error { namespaces := make(map[string]Namespace) if err := json.Unmarshal(data, &namespaces); err != nil { return err } for name, namespace := range namespaces { namespace.Name = name namespaces[name] = namespace } *c = namespaces return nil } func (c *LocationConstraints) UnmarshalJSON(data []byte) error { m := make(map[string]string) if err := json.Unmarshal(data, &m); err != nil { return err } *c = make(LocationConstraints, len(m)) for region, policy := range m { var pp netmap.PlacementPolicy if err := pp.DecodeString(policy); err == nil { (*c)[region] = pp continue } if err := pp.UnmarshalJSON([]byte(policy)); err == nil { (*c)[region] = pp continue } return fmt.Errorf("failed to parse location contraint '%s': '%s'", region, policy) } return nil } func (c LocationConstraints) MarshalJSON() ([]byte, error) { m := make(map[string]string, len(c)) for region, policy := range c { var sb strings.Builder if err := policy.WriteStringTo(&sb); err != nil { return nil, err } m[region] = sb.String() } return json.Marshal(m) }