PoshCode Archive  Artifact [0349b8ecee]

Artifact 0349b8ecee65232021e4ab15386d16e7fc4d0f435e60012511b590fa80784509:

  • File Invoke-Switch.ps1 — part of check-in [95b875cb88] at 2018-06-10 13:32:32 on branch trunk — A function to invoke a switch statement, in order to allow splatting to be used with switch (user: Kyle A Eppler size: 3603)

# encoding: ascii
# api: powershell
# title: Invoke-Switch
# description: A function to invoke a switch statement, in order to allow splatting to be used with switch
# version: 0.9
# type: function
# author: Kyle A Eppler
# license: CC0
# function: Invoke-Switch
# x-poshcode-id: 3873
# x-archived: 2013-01-22T14:51:03
# x-published: 2013-01-10T16:01:00
#
# Dependencies:
# This function, as written in this version, requires the existence of a repr function such as that defined by http://poshcode.org/3872 and its successors.
# I plan to post a new version of this function that does not limit the objects that may be used as either values to match against, or values to return, to only those that support round-trip serialization and deserialization to a string and back, using a repr function for the serialization. I’m first posting this version in case some technique used in it would be useful elsewhere.
#
New-Variable castDictionaryEntries
[System.Func[System.Collections.IEnumerable, System.Collections.Generic.IEnumerable[System.Collections.DictionaryEntry]]] `
    $castDictionaryEntries = [System.Delegate]::CreateDelegate(
        [System.Func[System.Collections.IEnumerable, System.Collections.Generic.IEnumerable[System.Collections.DictionaryEntry]]],
        [System.Linq.Enumerable].GetMethod(
            'Cast', @('Public, Static')).MakeGenericMethod(
                @([System.Collections.DictionaryEntry])))
Set-Variable castDictionaryEntries -Option ReadOnly

function Invoke-Switch {
    [CmdletBinding()]
    Param(
        [Parameter(Position=0, Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [System.Collections.IDictionary] $CaseMap,

        [Parameter(Position=1, Mandatory=$false)]
        [ValidateSet('Regex', 'Wildcard', 'Exact')]
        [string] $SwitchMode,

        [Parameter(Position=2, Mandatory=$false)]
        $DefaultCase,

        [Parameter(Position=3, Mandatory=$true, ValueFromPipeline=$true)]
        [AllowNull()]
        $InputObject,

        [Parameter()]
        [switch] $CaseSensitive)

    begin {
        New-Variable mode; [string] $mode = $null
        if($PSBoundParameters.ContainsKey('SwitchMode')) {
            $mode = " -$SwitchMode"
        }

        New-Variable caseOption; [string] $caseOption = $null
        if($CaseSensitive.IsPresent) {
            $caseOption = ' -CaseSensitive'
        }

        Set-Variable mode, caseOption -Option ReadOnly

        New-Variable value
        New-Variable cases; [string] $cases =
            $castDictionaryEntries.Invoke($CaseMap) `
                | % { $value = $_.Value; return $_.Key } `
                | repr `
                | % { return $_ } `
                    -End {
                            if($PSBoundParameters.TryGetValue(
                                'DefaultCase', [ref] $value))
                            {
                                Write-Output default
                            }
                        } `
                | % { return "$_ { Write-Output (,$(repr $value)) }" } `
                | Join-String -Separator ' '
        Set-Variable cases -Option ReadOnly

        New-Variable switchScript; [scriptblock] `
            $switchScript = $PSCmdlet.InvokeCommand.NewScriptBlock(
                "switch$mode$caseOption (`$InputObject) { $cases }")
        Set-Variable switchScript -Option ReadOnly

        $PSCmdlet.WriteDebug($switchScript)
    }

    process {
        . $switchScript | % { $PSCmdlet.WriteObject($_) }
    }
}