From 7cc062aba9d89463c233eac8a101cb9c7fea5785 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 1 Mar 2026 01:33:22 +0000 Subject: [PATCH 1/2] Add doc comments to CsvExtensions, TextConversions, and HtmlActivePatterns Documents public string conversion extension methods in StringExtensions, all TextConversions static methods, and the HtmlActivePatterns active patterns. Part of #1678. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/FSharp.Data.Csv.Core/CsvExtensions.fs | 26 +++++++++++++ .../HtmlActivePatterns.fs | 10 +++++ .../TextConversions.fs | 39 +++++++++++++++++-- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/FSharp.Data.Csv.Core/CsvExtensions.fs b/src/FSharp.Data.Csv.Core/CsvExtensions.fs index f1ba590ab..f267d3925 100644 --- a/src/FSharp.Data.Csv.Core/CsvExtensions.fs +++ b/src/FSharp.Data.Csv.Core/CsvExtensions.fs @@ -13,6 +13,9 @@ open FSharp.Data.Runtime [] type StringExtensions = + /// Converts the string to an integer. Fails if the value is not a valid integer. + /// The string to convert. + /// Optional culture info for parsing. Defaults to InvariantCulture. [] static member AsInteger(x: String, [] ?cultureInfo) = let cultureInfo = defaultArg cultureInfo CultureInfo.InvariantCulture @@ -21,6 +24,9 @@ type StringExtensions = | Some i -> i | _ -> failwithf "Not an int: %s" x + /// Converts the string to a 64-bit integer. Fails if the value is not a valid 64-bit integer. + /// The string to convert. + /// Optional culture info for parsing. Defaults to InvariantCulture. [] static member AsInteger64(x: String, [] ?cultureInfo) = let cultureInfo = defaultArg cultureInfo CultureInfo.InvariantCulture @@ -29,6 +35,9 @@ type StringExtensions = | Some i -> i | _ -> failwithf "Not an int64: %s" x + /// Converts the string to a decimal. Fails if the value is not a valid decimal. + /// The string to convert. + /// Optional culture info for parsing. Defaults to InvariantCulture. [] static member AsDecimal(x: String, [] ?cultureInfo) = let cultureInfo = defaultArg cultureInfo CultureInfo.InvariantCulture @@ -37,6 +46,10 @@ type StringExtensions = | Some d -> d | _ -> failwithf "Not a decimal: %s" x + /// Converts the string to a float. Fails if the value is not a valid float. + /// The string to convert. + /// Optional culture info for parsing. Defaults to InvariantCulture. + /// Values to treat as missing (NaN). Defaults to standard missing value strings. [] static member AsFloat(x: String, [] ?cultureInfo, [] ?missingValues) = let cultureInfo = defaultArg cultureInfo CultureInfo.InvariantCulture @@ -46,12 +59,17 @@ type StringExtensions = | Some f -> f | _ -> failwithf "Not a float: %s" x + /// Converts the string to a boolean. Fails if the value is not a valid boolean. + /// The string to convert. Accepts "true", "false", "yes", "no", "1", "0" (case-insensitive). [] static member AsBoolean(x: String) = match TextConversions.AsBoolean x with | Some b -> b | _ -> failwithf "Not a boolean: %s" x + /// Converts the string to a DateTime. Fails if the value is not a valid date/time string. + /// The string to convert. Accepts ISO 8601 format or MSFT JSON date format. + /// Optional culture info for parsing. Defaults to InvariantCulture. [] static member AsDateTime(x: String, [] ?cultureInfo) = let cultureInfo = defaultArg cultureInfo CultureInfo.InvariantCulture @@ -60,6 +78,9 @@ type StringExtensions = | Some d -> d | _ -> failwithf "Not a datetime: %s" x + /// Converts the string to a DateTimeOffset. Fails if the value is not a valid date/time with offset string. + /// The string to convert. Accepts ISO 8601 format with timezone offset or MSFT JSON date with offset. + /// Optional culture info for parsing. Defaults to InvariantCulture. [] static member AsDateTimeOffset(x, [] ?cultureInfo) = let cultureInfo = defaultArg cultureInfo CultureInfo.InvariantCulture @@ -68,6 +89,9 @@ type StringExtensions = | Some d -> d | _ -> failwithf "Not a datetime offset: %s" <| x + /// Converts the string to a TimeSpan. Fails if the value is not a valid time span string. + /// The string to convert. + /// Optional culture info for parsing. Defaults to InvariantCulture. [] static member AsTimeSpan(x: String, [] ?cultureInfo) = let cultureInfo = defaultArg cultureInfo CultureInfo.InvariantCulture @@ -76,6 +100,8 @@ type StringExtensions = | Some t -> t | _ -> failwithf "Not a time span: %s" x + /// Converts the string to a Guid. Fails if the value is not a valid GUID string. + /// The string to convert. [] static member AsGuid(x: String) = match x |> TextConversions.AsGuid with diff --git a/src/FSharp.Data.Html.Core/HtmlActivePatterns.fs b/src/FSharp.Data.Html.Core/HtmlActivePatterns.fs index cab4d61c1..43c9e35a1 100644 --- a/src/FSharp.Data.Html.Core/HtmlActivePatterns.fs +++ b/src/FSharp.Data.Html.Core/HtmlActivePatterns.fs @@ -2,7 +2,14 @@ namespace FSharp.Data #if HIDE_REPRESENTATION [] #endif +/// Active patterns for decomposing HtmlNode and HtmlAttribute values module HtmlActivePatterns = + + /// + /// Active pattern that decomposes an into one of four cases: + /// HtmlElement (name, attributes, child elements), HtmlText (text content), + /// HtmlComment (comment content), or HtmlCData (CDATA content). + /// let (|HtmlElement|HtmlText|HtmlComment|HtmlCData|) (node: HtmlNode) = match node with | HtmlNode.HtmlText content -> HtmlText(content) @@ -10,6 +17,9 @@ module HtmlActivePatterns = | HtmlNode.HtmlCData content -> HtmlCData(content) | HtmlNode.HtmlElement(name, attributes, elements) -> HtmlElement(name, attributes, elements) + /// + /// Active pattern that decomposes an into its name and value. + /// let (|HtmlAttribute|) (attribute: HtmlAttribute) = match attribute with | HtmlAttribute.HtmlAttribute(name, value) -> HtmlAttribute(name, value) diff --git a/src/FSharp.Data.Runtime.Utilities/TextConversions.fs b/src/FSharp.Data.Runtime.Utilities/TextConversions.fs index ee7779266..0226a0cce 100644 --- a/src/FSharp.Data.Runtime.Utilities/TextConversions.fs +++ b/src/FSharp.Data.Runtime.Utilities/TextConversions.fs @@ -113,19 +113,32 @@ type TextConversions private () = static member AsString str = if String.IsNullOrWhiteSpace str then None else Some str + /// Attempts to parse the string as an integer using the given culture. + /// The culture to use for parsing. + /// The string to parse. Currency and percentage adorners are removed before parsing. static member AsInteger cultureInfo text = Int32.TryParse(TextConversions.RemoveAdorners text, NumberStyles.Integer, cultureInfo) |> asOption + /// Attempts to parse the string as a 64-bit integer using the given culture. + /// The culture to use for parsing. + /// The string to parse. Currency and percentage adorners are removed before parsing. static member AsInteger64 cultureInfo text = Int64.TryParse(TextConversions.RemoveAdorners text, NumberStyles.Integer, cultureInfo) |> asOption + /// Attempts to parse the string as a decimal using the given culture. + /// The culture to use for parsing. + /// The string to parse. Currency and percentage adorners are removed before parsing. static member AsDecimal cultureInfo text = Decimal.TryParse(TextConversions.RemoveAdorners text, NumberStyles.Currency, cultureInfo) |> asOption - /// if useNoneForMissingValues is true, NAs are returned as None, otherwise Some Double.NaN is used + /// Attempts to parse the string as a float using the given culture. + /// Values to treat as missing. If matched, returns None or Some NaN depending on . + /// If true, missing values and NaN are returned as None; otherwise Some Double.NaN is used. + /// The culture to use for parsing. + /// The string to parse. static member AsFloat missingValues useNoneForMissingValues cultureInfo (text: string) = match text.Trim() with | OneOfIgnoreCase missingValues -> if useNoneForMissingValues then None else Some Double.NaN @@ -138,6 +151,8 @@ type TextConversions private () = else Some f) + /// Attempts to parse the string as a boolean. Accepts "true", "false", "yes", "no", "1", "0" (case-insensitive). + /// The string to parse. static member AsBoolean(text: string) = match text.Trim() with | StringEqualsIgnoreCase "true" @@ -148,9 +163,9 @@ type TextConversions private () = | StringEqualsIgnoreCase "0" -> Some false | _ -> None - /// Parse date time using either the JSON milliseconds format or using ISO 8601 - /// that is, either `/Date()/` or something - /// along the lines of `2013-01-28T00:37Z` + /// Attempts to parse the string as a DateTime using ISO 8601 format or MSFT JSON date format. + /// The culture to use for parsing. + /// The string to parse. Accepts e.g. 2013-01-28T00:37Z or /Date(1234567890)/. static member AsDateTime cultureInfo (text: string) = // Try parse "Date()" style format let matchesMS = msDateRegex.Value.Match(text.Trim()) @@ -167,6 +182,9 @@ type TextConversions private () = | ValueSome x -> Some x | ValueNone -> None + /// Attempts to parse the string as a DateTimeOffset using ISO 8601 format or MSFT JSON date with offset. + /// The culture to use for parsing. + /// The string to parse. The timezone offset must be present. static member AsDateTimeOffset cultureInfo (text: string) = // get TimeSpan presentation from 4-digit integers like 0000 or -0600 let getTimeSpanFromHourMin (hourMin: int) = @@ -203,12 +221,19 @@ type TextConversions private () = | false, _ -> None | _ -> None + /// Attempts to parse the string as a TimeSpan using the given culture. + /// The culture to use for parsing. + /// The string to parse. static member AsTimeSpan (cultureInfo: CultureInfo) (text: string) = match TimeSpan.TryParse(text, cultureInfo) with | true, t -> Some t | _ -> None #if NET6_0_OR_GREATER + /// Attempts to parse the string as a DateOnly using the given culture. + /// Strings that also parse as a DateTime with a non-zero time component are rejected. + /// The culture to use for parsing. + /// The string to parse. static member AsDateOnly (cultureInfo: CultureInfo) (text: string) = let mutable d = DateOnly.MinValue @@ -221,6 +246,10 @@ type TextConversions private () = else None + /// Attempts to parse the string as a TimeOnly using the given culture. + /// Strings that also parse as a DateTime with a specific non-today date are rejected. + /// The culture to use for parsing. + /// The string to parse. static member AsTimeOnly (cultureInfo: CultureInfo) (text: string) = let mutable t = TimeOnly.MinValue @@ -234,6 +263,8 @@ type TextConversions private () = None #endif + /// Attempts to parse the string as a Guid. + /// The string to parse. Leading and trailing whitespace is trimmed before parsing. static member AsGuid(text: string) = Guid.TryParse(text.Trim()) |> asOption module internal UnicodeHelper = From c63a0e4e770266f775050dc77aa74248a4a1b9bc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 1 Mar 2026 01:36:49 +0000 Subject: [PATCH 2/2] ci: trigger CI checks