Private/Converters.psm1

#!/usr/bin/env pwsh
using namespace System
using module ./Types.psm1
using module ./Enums.psm1

#Requires -Modules cliHelper.xconvert

class StringEnumConverter {
  static [string] ToWireValue([object]$value) {
    if ($null -eq $value) { return $null }
    return $value.ToString()
  }
}

class Promoter {
  static [object] Promote([object]$value, [object]$targetType) {
    if ($null -eq $value) { return $null }
    if ($targetType.IsAssignableFrom($value.GetType())) { return $value }

    if ($targetType -eq [PhoneNumber] -and $value -is [string]) {
      return [PhoneNumber]::new($value)
    }

    if ($targetType -eq [datetime] -and $value -is [string]) {
      return [datetime]::Parse($value, [Globalization.CultureInfo]::InvariantCulture)
    }

    return [Convert]::ChangeType($value, $targetType, [Globalization.CultureInfo]::InvariantCulture)
  }
}

class MarshalConverter {
  static [string] Serialize([object]$value) {
    if ($value -is [datetime]) {
      return ([datetime]$value).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
    }
    if ($value -is [bool]) {
      return $value.ToString().ToLowerInvariant()
    }
    return [string]$value
  }

  static [object] DeserializeJson([string]$json) {
    if ([string]::IsNullOrWhiteSpace($json)) { return $null }
    # Try to return as hashtable for easier access in resources
    try {
      return $json | ConvertFrom-Json -AsHashtable -ErrorAction Stop
    } catch {
      return $json | ConvertFrom-Json
    }
  }
}

class PrefixedCollapsibleMap {
  static [System.Collections.Generic.Dictionary[string, string]] Collapse([hashtable]$source, [string]$prefix) {
    $result = [System.Collections.Generic.Dictionary[string, string]]::new()
    if ($null -eq $source) { return $result }

    foreach ($k in $source.Keys) {
      $key = if ([string]::IsNullOrEmpty($prefix)) { [string]$k } else { "$prefix.$k" }
      $result[$key] = [MarshalConverter]::Serialize($source[$k])
    }

    return $result
  }
}