diff --git a/src/SwaggerProvider.DesignTime/Utils.fs b/src/SwaggerProvider.DesignTime/Utils.fs index a5978bd..ff3890c 100644 --- a/src/SwaggerProvider.DesignTime/Utils.fs +++ b/src/SwaggerProvider.DesignTime/Utils.fs @@ -332,6 +332,35 @@ module SchemaReader = resolvedPath } +module XmlDoc = + open System + + let private escapeXml(s: string) = + s.Replace("&", "&").Replace("<", "<").Replace(">", ">") + + /// Builds a structured XML doc string from summary, description, and parameter descriptions. + /// paramDescriptions is a sequence of (camelCaseName, description) pairs. + let buildXmlDoc (summary: string) (description: string) (paramDescriptions: (string * string) seq) = + let summaryPart = + if String.IsNullOrEmpty summary then + "" + else + $"{escapeXml summary}" + + let remarksPart = + if String.IsNullOrEmpty description || description = summary then + "" + else + $"{escapeXml description}" + + let paramParts = + [ for name, desc in paramDescriptions do + if not(String.IsNullOrWhiteSpace desc) then + yield $"{escapeXml desc}" ] + |> String.concat "" + + summaryPart + remarksPart + paramParts + type UniqueNameGenerator(?occupiedNames: string seq) = let hash = System.Collections.Generic.HashSet<_>() diff --git a/src/SwaggerProvider.DesignTime/v2/OperationCompiler.fs b/src/SwaggerProvider.DesignTime/v2/OperationCompiler.fs index 5e266c9..6d13c1f 100644 --- a/src/SwaggerProvider.DesignTime/v2/OperationCompiler.fs +++ b/src/SwaggerProvider.DesignTime/v2/OperationCompiler.fs @@ -252,8 +252,14 @@ type OperationCompiler(schema: SwaggerObject, defCompiler: DefinitionCompiler, i | true, None -> (awaitTask responseUnit).Raw ) - if not <| String.IsNullOrEmpty(op.Summary) then - m.AddXmlDoc(op.Summary) // TODO: Use description of parameters in docs + let xmlDoc = + let paramDescriptions = + [ for p in op.Parameters -> niceCamelName p.Name, p.Description ] + + XmlDoc.buildXmlDoc op.Summary op.Description paramDescriptions + + if not(String.IsNullOrEmpty xmlDoc) then + m.AddXmlDoc xmlDoc if op.Deprecated then m.AddObsoleteAttribute("Operation is deprecated", false) diff --git a/src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs b/src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs index 1782213..e075687 100644 --- a/src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs +++ b/src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs @@ -96,7 +96,7 @@ type OperationCompiler(schema: OpenApiDocument, defCompiler: DefinitionCompiler, let (|NoMediaType|_|)(content: IDictionary) = if isNull content || content.Count = 0 then Some() else None - let payloadMime, parameters, ctArgIndex = + let payloadTy, payloadMime, parameters, ctArgIndex = /// handles de-duplicating Swagger parameter names if the same parameter name /// appears in multiple locations in a given operation definition. let uniqueParamName usedNames (param: IOpenApiParameter) = @@ -195,7 +195,7 @@ type OperationCompiler(schema: OpenApiDocument, defCompiler: DefinitionCompiler, ctArgIndex, requiredProvidedParams @ optionalProvidedParams @ [ ctParam ] - payloadTy.ToMediaType(), parameters, ctArgIndex + payloadTy, payloadTy.ToMediaType(), parameters, ctArgIndex // find the inner type value let retMimeAndTy = @@ -494,8 +494,16 @@ type OperationCompiler(schema: OpenApiDocument, defCompiler: DefinitionCompiler, | _ -> Expr.Coerce(<@ RuntimeHelpers.asyncCast t %(awaitTask responseObj) @>, overallReturnType) ) - if not <| String.IsNullOrEmpty(operation.Summary) then - m.AddXmlDoc(operation.Summary) // TODO: Use description of parameters in docs + let xmlDoc = + let paramDescriptions = + [ for p in openApiParameters -> niceCamelName p.Name, p.Description + if not(isNull operation.RequestBody) then + yield niceCamelName(payloadTy.ToString()), operation.RequestBody.Description ] + + XmlDoc.buildXmlDoc operation.Summary operation.Description paramDescriptions + + if not(String.IsNullOrEmpty xmlDoc) then + m.AddXmlDoc xmlDoc if operation.Deprecated then m.AddObsoleteAttribute("Operation is deprecated", false)