@@ -6,6 +6,7 @@ open Microsoft.OpenApi.Models
66open Microsoft.OpenApi .Readers
77open System.IO
88open System.Text .RegularExpressions
9+ open NodaTime.Text
910
1011let inline trimLower ( s : string ) =
1112 if isNull s then None else
@@ -79,45 +80,104 @@ type PrimTypeKind =
7980
8081 member s.GetDefaultLiteral ( value : IOpenApiPrimitive ) =
8182 let fw t = failwithf " %s literal has been found for non-%s type" t t
82- let inline oneWay kind ( value : ^v ) ( toDefault : ^t -> DefaultableKind ) =
83+ let inline oneWay kind ( value : ^v ) ( toDefault : ^t -> ^o ) =
8384 match s with
8485 | x when x = kind ->
8586 let v = ( ^v :( member Value : ^t ) value)
8687 toDefault v
8788 | _ -> fw ( value.GetType() .Name)
88-
89- match value with
90- | :? OpenApiInteger as int ->
91- match s with
92- | Int -> DefaultableKind.Integer int.Value
93- | Long -> DefaultableKind.Long ( int64 int.Value)
94- | _ -> fw " integer"
95- | :? OpenApiLong as long ->
96- match s with
97- | Int -> DefaultableKind.Long ( int64 long.Value)
98- | Long -> DefaultableKind.Long long.Value
99- | _ -> fw " int64"
100- | :? OpenApiDouble as double -> oneWay Double double DefaultableKind.Double
101- | :? OpenApiBoolean as bool -> oneWay Bool bool DefaultableKind.Boolean
102- | :? OpenApiDateTime as dateTime -> oneWay ( String DateTimeString) dateTime DefaultableKind.DateTime
103- | :? OpenApiDate as date -> oneWay ( String DateString) date DefaultableKind.Date
104- | :? OpenApiPassword as pwd -> oneWay ( String PasswordString) pwd DefaultableKind.String
105- | :? OpenApiString as str ->
106- match s with
107- | String s ->
108- let inline oneWay x = oneWay ( String s) x
89+
90+ let nodaMatch () =
91+ let inline matchDateTime dt =
92+ let inline oneWay f = oneWay ( String DateTimeString) dt ( f >> Some)
93+ match Configuration.value.MapDateTimeInto with
94+ | Configuration.DateTimeGeneratedType.ZonedDateTime -> oneWay ( NodaTime.ZonedDateTime.FromDateTimeOffset >> ZonedDateTime)
95+ | Configuration.DateTimeGeneratedType.OffsetDateTime -> oneWay ( NodaTime.OffsetDateTime.FromDateTimeOffset >> OffsetDateTime)
96+ | Configuration.DateTimeGeneratedType.LocalDateTime -> oneWay ( fun dto -> NodaTime.LocalDateTime.FromDateTime dto.DateTime |> LocalDateTime)
97+ | Configuration.DateTimeGeneratedType.Instant -> oneWay ( fun dto -> NodaTime.OffsetDateTime.FromDateTimeOffset( dto) .ToInstant() |> Instant)
98+ match value with
99+ | :? OpenApiDateTime as dt -> matchDateTime dt
100+ | :? OpenApiDate as d -> oneWay ( String DateString) d ( NodaTime.LocalDate.FromDateTime >> LocalDate >> Some)
101+ | :? OpenApiString as str ->
109102 match s with
110- | PasswordString
111- | StringFormat.String -> oneWay str DefaultableKind.String
112- | Custom " uri"
113- | Custom " uriref" -> oneWay {| Value = System.Uri str.Value |} DefaultableKind.Uri
114- | Custom " uuid"
115- | Custom " guid"
116- | Custom " uid" -> oneWay {| Value = Guid.Parse str.Value |} DefaultableKind.Guid
117- | _ -> oneWay str DefaultableKind.String
118- | _ -> fw " string"
119- | v -> failwith ( sprintf " %A literals aren't supported for kind %A " v s)
103+ | String f ->
104+ let inline extract ( v : ParseResult < _ >) = v.Value
105+ let inline oneWay kind fn = oneWay ( String f) str ( fn >> kind >> Some)
106+ let inline oneWayP kind ( pattern : ^p ) =
107+ let inline parse v = ( ^p :( member Parse : string -> ParseResult<_>) pattern, v)
108+ oneWay kind ( parse >> extract)
109+ // use the same format strings as NodaTime serialization libraries define
110+ match f with
111+ | Custom " local-date"
112+ | DateString -> oneWayP LocalDate LocalDatePattern.Iso
113+ | DateTimeString -> {| Value = DateTimeOffset.Parse str.Value |} |> matchDateTime
114+ | Custom " instant" -> oneWayP Instant InstantPattern.ExtendedIso
115+ | Custom " time"
116+ | Custom " local-time" -> oneWayP LocalTime LocalTimePattern.GeneralIso
117+ | Custom " local-date-time" -> oneWayP LocalDateTime LocalDateTimePattern.ExtendedIso
118+ | Custom " offset-date-time" -> oneWayP OffsetDateTime OffsetDateTimePattern.Rfc3339
119+ | Custom " offset"
120+ | Custom " time-offset" -> oneWayP Offset OffsetPattern.GeneralInvariant
121+ | Custom " duration" -> oneWayP Duration DurationPattern.JsonRoundtrip
122+ | Custom " period" -> oneWayP Period PeriodPattern.Roundtrip
123+ | Custom " time-zone"
124+ | Custom " date-time-zone" ->
125+ let provider = NodaTime.DateTimeZoneProviders.Tzdb
126+ oneWay DateTimeZone ( fun zone -> provider.[ zone])
127+ | _ -> None
128+ | _ -> None
129+ | _ -> None
130+
131+ let defaultMatch () =
132+ match value with
133+ | :? OpenApiInteger as int ->
134+ match s with
135+ | Int -> DefaultableKind.Integer int.Value
136+ | Long -> DefaultableKind.Long ( int64 int.Value)
137+ | _ -> fw " integer"
138+ | :? OpenApiLong as long ->
139+ match s with
140+ | Int -> DefaultableKind.Long ( int64 long.Value)
141+ | Long -> DefaultableKind.Long long.Value
142+ | _ -> fw " int64"
143+ | :? OpenApiDouble as double -> oneWay Double double DefaultableKind.Double
144+ | :? OpenApiBoolean as bool -> oneWay Bool bool DefaultableKind.Boolean
145+ | :? OpenApiDateTime as dateTime -> oneWay ( String DateTimeString) dateTime DefaultableKind.DateTime
146+ | :? OpenApiDate as date -> oneWay ( String DateString) date DefaultableKind.Date
147+ | :? OpenApiPassword as pwd -> oneWay ( String PasswordString) pwd DefaultableKind.String
148+ | :? OpenApiString as str ->
149+ match s with
150+ | String s ->
151+ let inline oneWay x = oneWay ( String s) x
152+ match s with
153+ | PasswordString
154+ | StringFormat.String -> oneWay str DefaultableKind.String
155+ | Custom " uri"
156+ | Custom " uriref" -> oneWay {| Value = System.Uri str.Value |} DefaultableKind.Uri
157+ | Custom " uuid"
158+ | Custom " guid"
159+ | Custom " uid" -> oneWay {| Value = Guid.Parse str.Value |} DefaultableKind.Guid
160+ | _ -> oneWay str DefaultableKind.String
161+ | _ -> fw " string"
162+ | v -> failwith ( sprintf " %A literals aren't supported for kind %A " v s)
163+
164+ Some Configuration.value
165+ |> Option.filter ( fun c -> c.UseNodaTime)
166+ |> Option.bind ( fun _ -> nodaMatch())
167+ |> Option.map Noda
168+ |> Option.defaultWith defaultMatch
120169
170+ and NodaTimeDefaultableKind =
171+ | Instant of NodaTime.Instant
172+ | LocalDate of NodaTime.LocalDate
173+ | LocalTime of NodaTime.LocalTime
174+ | LocalDateTime of NodaTime.LocalDateTime
175+ | OffsetDateTime of NodaTime.OffsetDateTime
176+ | ZonedDateTime of NodaTime.ZonedDateTime
177+ | Offset of NodaTime.Offset
178+ | Duration of NodaTime.Duration
179+ | Period of NodaTime.Period
180+ | DateTimeZone of NodaTime.DateTimeZone
121181and DefaultableKind =
122182 | String of string
123183 | Integer of int
@@ -128,6 +188,7 @@ and DefaultableKind =
128188 | Boolean of bool
129189 | Uri of Uri
130190 | Guid of Guid
191+ | Noda of NodaTimeDefaultableKind
131192
132193/// IR for object schemas
133194and ObjectKind =
@@ -192,7 +253,7 @@ and TypeKind =
192253 | DU of DUKind
193254 | BuiltIn of string
194255 | NoType
195- static member Parse ( schema : OpenApiSchema ): TypeKind * DefaultableKind option =
256+ static member Parse ( schema : OpenApiSchema ): TypeKind * DefaultableKind option =
196257 if isNull schema then Prim PrimTypeKind.Any, None
197258 else
198259 let kind , def =
@@ -210,7 +271,7 @@ and TypeKind =
210271 ObjectKind.Create( schema) |> Object, None
211272 | PrimKind primType ->
212273 let prim = PrimTypeKind.Parse( primType, schema.Format)
213- let def = schema.Default |> Option.ofObj |> Option.map ( fun x -> x:?> IOpenApiPrimitive) |> Option.map prim.GetDefaultLiteral
274+ let def = schema.Default |> Option.ofObj |> Option.map ( fun x -> x:?> IOpenApiPrimitive) |> Option.map ( prim.GetDefaultLiteral)
214275 Prim prim, def
215276 if schema.Nullable && def.IsNone then
216277 ( Option kind), None
0 commit comments