-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConvertFrom-YamlMapping.ps1
More file actions
88 lines (77 loc) · 3.12 KB
/
Copy pathConvertFrom-YamlMapping.ps1
File metadata and controls
88 lines (77 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
function ConvertFrom-YamlMapping {
<#
.SYNOPSIS
Parses a YAML block-style mapping into a PSCustomObject or OrderedDictionary.
#>
[CmdletBinding()]
[OutputType([System.Collections.Specialized.OrderedDictionary], [pscustomobject])]
param(
[Parameter(Mandatory)] [pscustomobject] $Context,
[Parameter(Mandatory)] [int] $Indent,
[Parameter(Mandatory)] [int] $Depth
)
$lines = $Context.Lines
$map = [ordered]@{}
while ($Context.Index -lt $lines.Count) {
$line = $lines[$Context.Index]
if ($line.Indent -lt $Indent) { break }
if ($line.Indent -gt $Indent) {
throw "ConvertFrom-Yaml: unexpected indentation at line $($line.Number)."
}
if ($line.Content.StartsWith('- ') -or $line.Content -eq '-') {
# A sequence at the same indent as a mapping key is a sibling, not part of mapping.
break
}
$colonIdx = Find-YamlMappingColon -Content $line.Content
if ($colonIdx -lt 0) {
throw "ConvertFrom-Yaml: expected mapping key at line $($line.Number): '$($line.Content)'."
}
$rawKey = $line.Content.Substring(0, $colonIdx).Trim()
if ($rawKey.Length -ge 2 -and $rawKey[0] -eq "'" -and $rawKey[-1] -eq "'") {
$key = ($rawKey.Substring(1, $rawKey.Length - 2)) -replace "''", "'"
} elseif ($rawKey.Length -ge 2 -and $rawKey[0] -eq '"' -and $rawKey[-1] -eq '"') {
$key = Expand-YamlDoubleQuoted -Text ($rawKey.Substring(1, $rawKey.Length - 2))
} else {
$key = $rawKey
}
$rest = $line.Content.Substring($colonIdx + 1).Trim()
$Context.Index++
if ($rest.Length -gt 0) {
if ($rest -ceq '{}') {
$map[$key] = if ($Context.AsHashtable) { [ordered]@{} } else { [pscustomobject][ordered]@{} }
} elseif ($rest -ceq '[]') {
$map[$key] = @()
} else {
$map[$key] = ConvertFrom-YamlScalar -Raw $rest
}
continue
}
# Value on subsequent indented lines (mapping or sequence) or null.
if ($Context.Index -ge $lines.Count) {
$map[$key] = $null
continue
}
$next = $lines[$Context.Index]
if ($next.Indent -lt $Indent) {
$map[$key] = $null
continue
}
if ($next.Indent -eq $Indent) {
# Indentless sequences: YAML allows a sequence to start at the same indent as the
# parent mapping key (e.g. "key:\n- a\n- b"). Parse these as the key's value.
if ($next.Content.StartsWith('- ') -or $next.Content -eq '-') {
$map[$key] = ConvertFrom-YamlSequence -Context $Context -Indent $Indent -Depth ($Depth + 1)
continue
}
$map[$key] = $null
continue
}
$childIndent = $next.Indent
$value = ConvertFrom-YamlNode -Context $Context -Indent $childIndent -Depth ($Depth + 1)
$map[$key] = $value
}
if ($Context.AsHashtable) {
return $map
}
return [pscustomobject]$map
}