Functions/ConvertFrom-WhiskeyYamlScalar.ps1
function ConvertFrom-WhiskeyYamlScalar { <# .SYNOPSIS Converts a string that came from a YAML configuation file into a strongly-typed object. .DESCRIPTION The `ConvertFrom-WhiskeyYamlScalar` function converts a string that came from a YAML configuration file into a strongly-typed object according to the parsing rules in the YAML specification. It converts strings into booleans, integers, floating-point numbers, and timestamps. See the YAML specification for examples on how to represent these values in your YAML file. It will convert: * `y`, `yes`, `true`, and `on` to `$true` * `n`, `no`, `false`, and `off` to `$false` * Numbers to `int32` or `int64` types. Numbers can be prefixed with `0x` (for hex), `0b` (for bits), or `0` for octal. * Floating point numbers to `double`, or `single` types. Floating point numbers can be expressed as decimals (`1.5`), or with scientific notation (`6.8523015e+5`). * `~`, `null`, and `` to `$null` * timestamps (e.g. `2001-12-14t21:59:43.10-05:00`) to date If it can't convert a string into a known type, `ConvertFrom-WhiskeyYamlScalar` writes an error. .EXAMPLE $value | ConvertFrom-WhiskeyYamlScalar Demonstrates how to pipe values to `ConvertFrom-WhiskeyYamlScalar`. #> [CmdletBinding()] param( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [AllowEmptyString()] [AllowNull()] [string] # The object to convert. $InputObject ) process { Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState if( [string]::IsNullOrEmpty($InputObject) -or $InputObject -match '^(~|null)' ) { return $null } if( $InputObject -match '^(y|yes|n|no|true|false|on|off)$' ) { return $InputObject -match '^(y|yes|true|on)$' } # Integer $regex = @' ^( [-+]?0b[0-1_]+ # (base 2) |[-+]?0[0-7_]+ # (base 8) |[-+]?(0|[1-9][0-9_]*) # (base 10) |[-+]?0x[0-9a-fA-F_]+ # (base 16) |[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+ # (base 60) )$ '@ if( [Text.RegularExpressions.Regex]::IsMatch($InputObject, $regex, [Text.RegularExpressions.RegexOptions]::IgnorePatternWhitespace) ) { [int64]$int64 = 0 $value = $InputObject -replace '_','' if( $value -match '^0x' -and [int64]::TryParse(($value -replace '0x',''), [Globalization.NumberStyles]::HexNumber, $null,[ref]$int64)) { } elseif( $value -match '^0b' ) { $int64 = [Convert]::ToInt64(($value -replace ('^0b','')),2) } elseif( $value -match '^0' ) { $int64 = [Convert]::ToInt64($value,8) } elseif( [int64]::TryParse($value,[ref]$int64) ) { } if( $int64 -gt [Int32]::MaxValue ) { return $int64 } return [int32]$int64 } $regex = @' ^( [-+]?([0-9][0-9_]*)?\.[0-9_]*([eE][-+][0-9]+)? # (base 10) |[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]* # (base 60) |[-+]?\.(inf|Inf|INF) # (infinity) |\.(nan|NaN|NAN) # (not a number) )$ '@ if( [Text.RegularExpressions.Regex]::IsMatch($InputObject, $regex, [Text.RegularExpressions.RegexOptions]::IgnorePatternWhitespace) ) { $value = $InputObject -replace '_','' [double]$double = 0.0 if( $value -eq '.NaN' ) { return [double]::NaN } if( $value -match '-\.inf' ) { return [double]::NegativeInfinity } if( $value -match '\+?.inf' ) { return [double]::PositiveInfinity } if( [double]::TryParse($value,[ref]$double) ) { return $double } } $regex = '^\d\d\d\d-\d\d?-\d\d?(([Tt]|[ \t]+)\d\d?\:\d\d\:\d\d(\.\d+)?(Z|\ *[-+]\d\d?(:\d\d)?)?)?$' if( [Text.RegularExpressions.Regex]::IsMatch($InputObject, $regex, [Text.RegularExpressions.RegexOptions]::IgnorePatternWhitespace) ) { [DateTime]$datetime = [DateTime]::MinValue if( ([DateTime]::TryParse(($InputObject -replace 'T',' '),[ref]$datetime)) ) { return $datetime } } Write-Error -Message ('Unable to convert scalar value ''{0}''. See http://yaml.org/type/ for documentation on YAML''s scalars.' -f $InputObject) -ErrorAction $ErrorActionPreference } } |