diff --git a/utils/consts.go b/utils/consts.go index 2ee7649da..a45e2d912 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -701,6 +701,7 @@ const ( ResourceUsage = "ResourceUsage" MetaStrip = "*strip" MetaDuration = "*duration" + MetaDurationFormat = "*durfmt" MetaLibPhoneNumber = "*libphonenumber" MetaTimeString = "*time_string" MetaIP2Hex = "*ip2hex" diff --git a/utils/dataconverter.go b/utils/dataconverter.go index da1825964..5040cb816 100644 --- a/utils/dataconverter.go +++ b/utils/dataconverter.go @@ -79,6 +79,8 @@ func NewDataConverter(params string) (conv DataConverter, err error) { return new(JSONConverter), nil case params == MetaDuration: return NewDurationConverter(EmptyString) + case strings.HasPrefix(params, MetaDurationFormat): + return NewDurationFormatConverter(params[len(MetaDurationFormat)+1:]) case params == MetaIP2Hex: return new(IP2HexConverter), nil case params == MetaString2Hex: @@ -274,6 +276,30 @@ func (mS *DurationConverter) Convert(in any) ( return IfaceAsDuration(in) } +func NewDurationFormatConverter(params string) (hdlr DataConverter, err error) { + return &DurationFormatConverter{Layout: params}, nil +} + +// DurationFormatConverter formats duration in the same way Time is formatted as string +type DurationFormatConverter struct { + Layout string +} + +func (dfc *DurationFormatConverter) Convert(in any) ( + out any, err error) { + z := time.Unix(0, 0).UTC() + dur, err := IfaceAsDuration(in) + if err != nil { + return nil, err + } + if dfc.Layout == EmptyString { + out = z.Add(time.Duration(dur)).Format("15:04:05") + return + } + out = z.Add(time.Duration(dur)).Format(dfc.Layout) + return +} + // NewPhoneNumberConverter create a new phoneNumber converter // If the format isn't specify by default we use NATIONAL // Possible fromats are : E164(0) , INTERNATIONAL(1) , NATIONAL(2) ,RFC3966(3) diff --git a/utils/dataconverter_test.go b/utils/dataconverter_test.go index d78c07641..a7df03030 100644 --- a/utils/dataconverter_test.go +++ b/utils/dataconverter_test.go @@ -41,6 +41,42 @@ func TestDataConvertersConvertString(t *testing.T) { } } +func TestConvertDurationFormat1(t *testing.T) { + dcs := &DataConverters{ + &DurationFormatConverter{ + Layout: "15:04:05", + }, + } + if rcv, err := dcs.ConvertString("15m"); err != nil { + t.Error(err) + } else if rcv != "00:15:00" { + t.Errorf("Expecting: <%+q>, received: <%+q>", "00:15:00", rcv) + } +} +func TestConvertDurationFormat2(t *testing.T) { + dcs := &DataConverters{ + &DurationFormatConverter{ + Layout: "15-04-05.999999999", + }, + } + if rcv, err := dcs.ConvertString("20s423ns"); err != nil { + t.Error(err) + } else if rcv != "00-00-20.000000423" { + t.Errorf("Expecting: <%+q>, received: <%+q>", "00-00-20.000000423", rcv) + } +} + +func TestConvertDurationFormatDefault(t *testing.T) { + dcs := &DataConverters{ + &DurationFormatConverter{}, + } + if rcv, err := dcs.ConvertString("15m"); err != nil { + t.Error(err) + } else if rcv != "00:15:00" { + t.Errorf("Expecting: <%+q>, received: <%+q>", "00:15:00", rcv) + } +} + func TestNewDataConverter(t *testing.T) { a, err := NewDataConverter(MetaDurationSeconds) if err != nil { @@ -169,6 +205,13 @@ func TestNewDataConverter(t *testing.T) { if !reflect.DeepEqual(tm, expTime) { t.Errorf("Expected %+v received: %+v", expTime, tm) } + expected := &DurationFormatConverter{Layout: "15:04:05"} + if durFmt, err := NewDataConverter(MetaDurationFormat + ":15:04:05"); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(durFmt, expected) { + t.Errorf("Expected %+v received: %+v", expected, durFmt) + } + } func TestNewDataConverterMustCompile(t *testing.T) {