diff --git a/src/SwaggerProvider.Runtime/RuntimeHelpers.fs b/src/SwaggerProvider.Runtime/RuntimeHelpers.fs index c7f07e3a..bf709f98 100644 --- a/src/SwaggerProvider.Runtime/RuntimeHelpers.fs +++ b/src/SwaggerProvider.Runtime/RuntimeHelpers.fs @@ -376,9 +376,16 @@ module RuntimeHelpers = if vTy = typeof then sb.Append('"').Append(v.ToString()).Append('"') |> ignore + elif vTy.FullName = dateOnlyTypeName then + sb.Append(formatDateOrTimeValue "yyyy-MM-dd" vTy v) |> ignore + elif vTy.FullName = timeOnlyTypeName then + sb.Append(formatDateOrTimeValue "HH:mm:ss.FFFFFFF" vTy v) |> ignore elif vTy.IsArray then sb.Append('[') |> ignore let mutable firstEl = true + let elTy = vTy.GetElementType() + let isDateOnly = not(isNull elTy) && elTy.FullName = dateOnlyTypeName + let isTimeOnly = not(isNull elTy) && elTy.FullName = timeOnlyTypeName for x in (v :?> Array) |> Seq.cast do if not firstEl then @@ -389,7 +396,14 @@ module RuntimeHelpers = if isNull x then sb.Append("null") |> ignore else - sb.Append(x.ToString()) |> ignore + let xTy = x.GetType() + + if isDateOnly then + sb.Append(formatDateOrTimeValue "yyyy-MM-dd" xTy x) |> ignore + elif isTimeOnly then + sb.Append(formatDateOrTimeValue "HH:mm:ss.FFFFFFF" xTy x) |> ignore + else + sb.Append(x.ToString()) |> ignore sb.Append(']') |> ignore else diff --git a/tests/SwaggerProvider.Tests/RuntimeHelpersTests.fs b/tests/SwaggerProvider.Tests/RuntimeHelpersTests.fs index 14ed60c0..5dfa7057 100644 --- a/tests/SwaggerProvider.Tests/RuntimeHelpersTests.fs +++ b/tests/SwaggerProvider.Tests/RuntimeHelpersTests.fs @@ -1128,6 +1128,18 @@ type FmtMulti(age: int, name: string) = type FmtArray(tags: string[]) = member _.Tags = tags +type FmtDateOnly(date: DateOnly) = + member _.Date = date + +type FmtTimeOnly(time: TimeOnly) = + member _.Time = time + +type FmtDateOnlyArray(dates: DateOnly[]) = + member _.Dates = dates + +type FmtTimeOnlyArray(times: TimeOnly[]) = + member _.Times = times + module FormatObjectTests = @@ -1177,6 +1189,31 @@ module FormatObjectTests = let obj = FmtMulti(30, "Bob") formatObject obj |> shouldEqual "{Age=30; Name=\"Bob\"}" + [] + let ``formatObject formats DateOnly property as ISO 8601``() = + let obj = FmtDateOnly(DateOnly(2025, 7, 4)) + formatObject obj |> shouldEqual "{Date=2025-07-04}" + + [] + let ``formatObject formats TimeOnly property using HH:mm:ss.FFFFFFF``() = + let obj = FmtTimeOnly(TimeOnly(14, 30, 0)) + formatObject obj |> shouldEqual "{Time=14:30:00}" + + [] + let ``formatObject formats TimeOnly property with sub-second precision``() = + let obj = FmtTimeOnly(TimeOnly(9, 5, 3, 123)) + formatObject obj |> shouldEqual "{Time=09:05:03.123}" + + [] + let ``formatObject formats DateOnly array elements as ISO 8601``() = + let obj = FmtDateOnlyArray([| DateOnly(2025, 1, 1); DateOnly(2025, 12, 31) |]) + formatObject obj |> shouldEqual "{Dates=[2025-01-01; 2025-12-31]}" + + [] + let ``formatObject formats TimeOnly array elements using HH:mm:ss.FFFFFFF``() = + let obj = FmtTimeOnlyArray([| TimeOnly(8, 0, 0); TimeOnly(14, 30, 45, 500) |]) + formatObject obj |> shouldEqual "{Times=[08:00:00; 14:30:45.5]}" + module ToFormUrlEncodedContentTests =