Files
mq/handlers/format_handler.go
2025-08-12 09:02:29 +05:45

261 lines
6.1 KiB
Go

package handlers
import (
"context"
"fmt"
"strconv"
"strings"
"time"
"github.com/oarkflow/json"
"github.com/oarkflow/mq"
"github.com/oarkflow/mq/dag"
)
// FormatHandler handles data formatting operations
type FormatHandler struct {
dag.Operation
}
func (h *FormatHandler) ProcessTask(ctx context.Context, task *mq.Task) mq.Result {
var data map[string]any
err := json.Unmarshal(task.Payload, &data)
if err != nil {
return mq.Result{Error: fmt.Errorf("failed to unmarshal task payload: %w", err), Ctx: ctx}
}
formatType, ok := h.Payload.Data["format_type"].(string)
if !ok {
return mq.Result{Error: fmt.Errorf("format_type not specified"), Ctx: ctx}
}
var result map[string]any
switch formatType {
case "string":
result = h.formatToString(data)
case "number":
result = h.formatToNumber(data)
case "date":
result = h.formatDate(data)
case "currency":
result = h.formatCurrency(data)
case "uppercase":
result = h.formatUppercase(data)
case "lowercase":
result = h.formatLowercase(data)
case "capitalize":
result = h.formatCapitalize(data)
case "trim":
result = h.formatTrim(data)
default:
return mq.Result{Error: fmt.Errorf("unsupported format_type: %s", formatType), Ctx: ctx}
}
resultPayload, err := json.Marshal(result)
if err != nil {
return mq.Result{Error: fmt.Errorf("failed to marshal result: %w", err), Ctx: ctx}
}
return mq.Result{Payload: resultPayload, Ctx: ctx}
}
func (h *FormatHandler) formatToString(data map[string]any) map[string]any {
result := make(map[string]any)
fields := h.getTargetFields(data)
for key, value := range data {
if len(fields) == 0 || contains(fields, key) {
result[key] = fmt.Sprintf("%v", value)
} else {
result[key] = value
}
}
return result
}
func (h *FormatHandler) formatToNumber(data map[string]any) map[string]any {
result := make(map[string]any)
fields := h.getTargetFields(data)
for key, value := range data {
if len(fields) == 0 || contains(fields, key) {
if str, ok := value.(string); ok {
if num, err := strconv.ParseFloat(str, 64); err == nil {
result[key] = num
} else {
result[key] = value // Keep original if conversion fails
}
} else {
result[key] = value
}
} else {
result[key] = value
}
}
return result
}
func (h *FormatHandler) formatDate(data map[string]any) map[string]any {
result := make(map[string]any)
fields := h.getTargetFields(data)
dateFormat := h.getDateFormat()
for key, value := range data {
if len(fields) == 0 || contains(fields, key) {
if str, ok := value.(string); ok {
if t, err := time.Parse(time.RFC3339, str); err == nil {
result[key] = t.Format(dateFormat)
} else if t, err := time.Parse("2006-01-02", str); err == nil {
result[key] = t.Format(dateFormat)
} else {
result[key] = value // Keep original if parsing fails
}
} else {
result[key] = value
}
} else {
result[key] = value
}
}
return result
}
func (h *FormatHandler) formatCurrency(data map[string]any) map[string]any {
result := make(map[string]any)
fields := h.getTargetFields(data)
currency := h.getCurrency()
for key, value := range data {
if len(fields) == 0 || contains(fields, key) {
if num, ok := value.(float64); ok {
result[key] = fmt.Sprintf("%s%.2f", currency, num)
} else if str, ok := value.(string); ok {
if num, err := strconv.ParseFloat(str, 64); err == nil {
result[key] = fmt.Sprintf("%s%.2f", currency, num)
} else {
result[key] = value
}
} else {
result[key] = value
}
} else {
result[key] = value
}
}
return result
}
func (h *FormatHandler) formatUppercase(data map[string]any) map[string]any {
result := make(map[string]any)
fields := h.getTargetFields(data)
for key, value := range data {
if len(fields) == 0 || contains(fields, key) {
if str, ok := value.(string); ok {
result[key] = strings.ToUpper(str)
} else {
result[key] = value
}
} else {
result[key] = value
}
}
return result
}
func (h *FormatHandler) formatLowercase(data map[string]any) map[string]any {
result := make(map[string]any)
fields := h.getTargetFields(data)
for key, value := range data {
if len(fields) == 0 || contains(fields, key) {
if str, ok := value.(string); ok {
result[key] = strings.ToLower(str)
} else {
result[key] = value
}
} else {
result[key] = value
}
}
return result
}
func (h *FormatHandler) formatCapitalize(data map[string]any) map[string]any {
result := make(map[string]any)
fields := h.getTargetFields(data)
for key, value := range data {
if len(fields) == 0 || contains(fields, key) {
if str, ok := value.(string); ok {
result[key] = strings.Title(strings.ToLower(str))
} else {
result[key] = value
}
} else {
result[key] = value
}
}
return result
}
func (h *FormatHandler) formatTrim(data map[string]any) map[string]any {
result := make(map[string]any)
fields := h.getTargetFields(data)
for key, value := range data {
if len(fields) == 0 || contains(fields, key) {
if str, ok := value.(string); ok {
result[key] = strings.TrimSpace(str)
} else {
result[key] = value
}
} else {
result[key] = value
}
}
return result
}
func (h *FormatHandler) getTargetFields(data map[string]any) []string {
if fields, ok := h.Payload.Data["fields"].([]interface{}); ok {
var result []string
for _, field := range fields {
if str, ok := field.(string); ok {
result = append(result, str)
}
}
return result
}
return nil
}
func (h *FormatHandler) getDateFormat() string {
if format, ok := h.Payload.Data["date_format"].(string); ok {
return format
}
return "2006-01-02" // Default date format
}
func (h *FormatHandler) getCurrency() string {
if currency, ok := h.Payload.Data["currency"].(string); ok {
return currency
}
return "$" // Default currency symbol
}
func contains(slice []string, item string) bool {
for _, s := range slice {
if s == item {
return true
}
}
return false
}
func NewFormatHandler(id string) *FormatHandler {
return &FormatHandler{
Operation: dag.Operation{ID: id, Key: "format", Type: dag.Function, Tags: []string{"data", "transformation"}},
}
}