package model import "strings" var supportedRailOperations = map[RailOperation]struct{}{ RailOperationDebit: {}, RailOperationCredit: {}, RailOperationExternalDebit: {}, RailOperationExternalCredit: {}, RailOperationMove: {}, RailOperationSend: {}, RailOperationFee: {}, RailOperationObserveConfirm: {}, RailOperationFXConvert: {}, RailOperationBlock: {}, RailOperationRelease: {}, } // ParseRailOperation canonicalizes string values into a RailOperation token. func ParseRailOperation(value string) RailOperation { clean := strings.ToUpper(strings.TrimSpace(value)) if clean == "" { return RailOperationUnspecified } return RailOperation(clean) } // IsSupportedRailOperation reports whether op is recognized by payment planning. func IsSupportedRailOperation(op RailOperation) bool { _, ok := supportedRailOperations[ParseRailOperation(string(op))] return ok } // NormalizeRailOperations trims, uppercases, deduplicates, and filters unknown values. func NormalizeRailOperations(values []RailOperation) []RailOperation { if len(values) == 0 { return nil } result := make([]RailOperation, 0, len(values)) seen := map[RailOperation]bool{} for _, value := range values { op := ParseRailOperation(string(value)) if op == RailOperationUnspecified || !IsSupportedRailOperation(op) || seen[op] { continue } seen[op] = true result = append(result, op) } if len(result) == 0 { return nil } return result } // NormalizeRailOperationStrings normalizes string operation values. func NormalizeRailOperationStrings(values []string) []RailOperation { if len(values) == 0 { return nil } ops := make([]RailOperation, 0, len(values)) for _, value := range values { ops = append(ops, ParseRailOperation(value)) } return NormalizeRailOperations(ops) } // HasRailOperation checks whether ops includes action. func HasRailOperation(ops []RailOperation, action RailOperation) bool { want := ParseRailOperation(string(action)) if want == RailOperationUnspecified { return false } for _, op := range ops { if ParseRailOperation(string(op)) == want { return true } } return false } // RailCapabilitiesFromOperations derives legacy capability flags from explicit operations. func RailCapabilitiesFromOperations(ops []RailOperation) RailCapabilities { normalized := NormalizeRailOperations(ops) return RailCapabilities{ CanPayIn: HasRailOperation(normalized, RailOperationExternalDebit), CanPayOut: HasRailOperation(normalized, RailOperationSend) || HasRailOperation(normalized, RailOperationExternalCredit), CanReadBalance: false, CanSendFee: HasRailOperation(normalized, RailOperationFee), RequiresObserveConfirm: HasRailOperation(normalized, RailOperationObserveConfirm), CanBlock: HasRailOperation(normalized, RailOperationBlock), CanRelease: HasRailOperation(normalized, RailOperationRelease), } }