package audit import ( "strings" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" "github.com/mr-tron/base58" ) type ModelType[T any] interface { ReadFromV2(m T) error String() string } func TargetFromRef[T any](ref *T, model ModelType[T]) Target { if ref == nil { return stringTarget{s: NotDefined} } if err := model.ReadFromV2(*ref); err != nil { return stringTarget{s: InvalidValue} } return stringTarget{s: model.String()} } func TargetFromRefs[T any](refs []*T, model ModelType[T]) Target { if len(refs) == 0 { return stringTarget{s: NotDefined} } sb := &strings.Builder{} for idx, ref := range refs { if idx > 0 { sb.WriteString(";") } if ref == nil { sb.WriteString(Empty) continue } if err := model.ReadFromV2(*ref); err != nil { sb.WriteString(InvalidValue) } else { sb.WriteString(model.String()) } } return sb } type stringTarget struct { s string } func (t stringTarget) String() string { return t.s } func TargetFromString(s string) Target { if len(s) == 0 { s = Empty } return stringTarget{s: s} } func TargetFromStringSlice(s []string) Target { if len(s) == 0 { return stringTarget{s: NotDefined} } sb := &strings.Builder{} for i, v := range s { if i > 0 { sb.WriteString(";") } if len(v) == 0 { sb.WriteString(Empty) } else { sb.WriteString(v) } } return sb } func TargetFromChainID(chainTargetType, chainTargetName string, chainID []byte) Target { if len(chainTargetType) == 0 && len(chainTargetName) == 0 && len(chainID) == 0 { return stringTarget{s: NotDefined} } t, n, c := Empty, Empty, Empty if len(chainTargetType) > 0 { t = chainTargetType } if len(chainTargetName) > 0 { n = chainTargetName } if len(chainID) > 0 { c = string(chainID) } return stringTarget{s: t + ":" + n + ":" + c} } func TargetFromShardIDs(v [][]byte) Target { if len(v) == 0 { return stringTarget{s: NotDefined} } sb := &strings.Builder{} for i, s := range v { if i > 0 { sb.WriteString(";") } if len(s) == 0 { sb.WriteString(Empty) } else { sb.WriteString(base58.Encode(s)) } } return sb } func TargetFromTreeID(containerID []byte, treeID string) Target { if len(containerID) == 0 && len(treeID) == 0 { return stringTarget{s: NotDefined} } c, t := Empty, Empty if len(containerID) > 0 { var cnr cid.ID if err := cnr.Decode(containerID); err != nil { c = InvalidValue } else { c = cnr.EncodeToString() } } if len(treeID) > 0 { t = treeID } return stringTarget{s: c + ":" + t} } func TargetFromContainerIDObjectID(containerID *refs.ContainerID, objectID *refs.ObjectID) Target { if containerID == nil && objectID == nil { return stringTarget{s: NotDefined} } c, o := Empty, Empty if containerID != nil { var cnr cid.ID if err := cnr.ReadFromV2(*containerID); err != nil { c = InvalidValue } else { c = cnr.EncodeToString() } } if objectID != nil { var obj oid.ID if err := obj.ReadFromV2(*objectID); err != nil { o = InvalidValue } else { o = obj.EncodeToString() } } return stringTarget{s: c + "/" + o} }