Skip to content

Commit 1dbbc81

Browse files
committed
Make time.format, time.parse pervasive
1 parent 82f67e1 commit 1dbbc81

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# v next
2+
3+
- Many Ari functions were written with scalar use-cases in mind, but many of them would be more powerful if they supported both scalar and array arguments. Such pervasive/broadcasting behavior has been added to the following functions:
4+
- `time.format` _(also swapped arg order)_
5+
- `time.parse`
6+
17
# v0.1.4 2024-10-14
28

39
- Corrects the version of itself that Ari reports to Goal, surfaced via `rt.get"v"`

time.go

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -714,18 +714,34 @@ func VFTimeParse(_ *goal.Context, args []goal.V) goal.V {
714714
if !ok {
715715
return panicType("slayout time.parse svalue", "sformat", x)
716716
}
717+
layout := string(layoutS)
717718
switch len(args) {
718719
case dyadic:
719720
y := args[0]
720-
valueS, ok := y.BV().(goal.S)
721-
if !ok {
722-
return panicType("slayout time.parse svalue", "svalue", y)
723-
}
724-
t, err := time.Parse(string(layoutS), string(valueS))
725-
if err != nil {
726-
return goal.NewPanicError(err)
721+
switch yv := y.BV().(type) {
722+
case goal.S:
723+
if !ok {
724+
return panicType("slayout time.parse svalue", "svalue", y)
725+
}
726+
t, err := time.Parse(layout, string(yv))
727+
if err != nil {
728+
return goal.NewPanicError(err)
729+
}
730+
return goal.NewV(&Time{&t})
731+
case *goal.AS:
732+
r := make([]goal.V, yv.Len())
733+
for i, yi := range yv.Slice {
734+
t, err := time.Parse(layout, yi)
735+
if err != nil {
736+
return goal.NewPanicError(err)
737+
}
738+
r[i] = goal.NewV(&Time{&t})
739+
}
740+
return goal.NewAV(r)
741+
default:
742+
return goal.Panicf("slayout time.parse svalue : svalue must be a string or array of strings, "+
743+
"but received a %q: %v", yv.Type(), yv)
727744
}
728-
return goal.NewV(&Time{&t})
729745
default:
730746
return goal.Panicf("time.parse : too many arguments (%d), expects 2 arguments", len(args))
731747
}
@@ -734,19 +750,33 @@ func VFTimeParse(_ *goal.Context, args []goal.V) goal.V {
734750
// Implements time.format function.
735751
func VFTimeFormat(_ *goal.Context, args []goal.V) goal.V {
736752
x := args[len(args)-1]
737-
t, ok := x.BV().(*Time)
753+
formatS, ok := x.BV().(goal.S)
738754
if !ok {
739-
return panicType("time time.format sformat", "time", x)
755+
return panicType("sformat time.format time", "sformat", x)
740756
}
757+
format := string(formatS)
741758
switch len(args) {
742759
case dyadic:
743760
y := args[0]
744-
formatS, ok := y.BV().(goal.S)
745-
if !ok {
746-
return panicType("time time.format sformat", "sformat", y)
761+
switch yv := y.BV().(type) {
762+
case *Time:
763+
s := yv.Time.Format(format)
764+
return goal.NewS(s)
765+
case *goal.AV:
766+
r := make([]string, yv.Len())
767+
for i, yi := range yv.Slice {
768+
if t, ok := yi.BV().(*Time); ok {
769+
r[i] = t.Time.Format(format)
770+
} else {
771+
return goal.Panicf("sformat time.format time : expected array of times, "+
772+
"but array has a %q value: %v", yi.Type(), yi)
773+
}
774+
}
775+
return goal.NewAS(r)
776+
default:
777+
return goal.Panicf("sformat time.format time : expected time or array of times, "+
778+
"but received a %q: %v", yv.Type(), yv)
747779
}
748-
s := t.Time.Format(string(formatS))
749-
return goal.NewS(s)
750780
default:
751781
return goal.Panicf("time.format : too many arguments (%d), expects 2 arguments", len(args))
752782
}

0 commit comments

Comments
 (0)