-
Notifications
You must be signed in to change notification settings - Fork 0
/
ConvertFrom-JsonFast.psm1
147 lines (118 loc) · 4.46 KB
/
ConvertFrom-JsonFast.psm1
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Add-Type -TypeDefinition @"
using System;
using System.IO;
using System.Linq;
using System.Collections;
using System.Text.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static class JsonHelper
{
public static object Deserialize(string json, Int32 depth)
{
JsonDocumentOptions options = new JsonDocumentOptions();
options.MaxDepth = depth;
JsonDocument thisDocument = JsonDocument.Parse(json, options);
return ToObject(thisDocument.RootElement);
}
public static object ToObject(JsonElement element)
{
JsonValueKind thisKind = element.ValueKind;
switch (element.ValueKind) {
case JsonValueKind.Object:
var Properties = element.EnumerateObject();
return new Hashtable(Properties.ToDictionary(prop => prop.Name,
prop => ToObject(prop.Value)
));
case JsonValueKind.Array:
var Entries = element.EnumerateArray();
return Entries.Select(ToObject).ToArray();
case JsonValueKind.True:
return true;
case JsonValueKind.False:
return false;
case JsonValueKind.String:
return element.GetString();
case JsonValueKind.Number:
if (element.TryGetInt32(out _)) { return element.GetInt32(); }
if (element.TryGetInt64(out _)) { return element.GetInt64(); }
return element.GetDouble();
default:
return null;
}
}
}
"@ -ReferencedAssemblies netstandard,System.Collections,System.Linq,System,System.IO,System.Text.Json,Newtonsoft.Json,System.Memory
Function ConvertFrom-JsonFast {
<#
.SYNOPSIS
Converts a json string to a real object
.DESCRIPTION
Converts a json string to a real object
.PARAMETER InputObject
The string of json to convert
.EXAMPLE
ConvertFrom-JsonFast -InputObject "{""Tom"": 5}"
.NOTES
Objects will be returned as Hashtables and not as pscustomobjects
#>
param (
[Parameter(ValuefromPipeline=$True)]
$InputObject,
[int] $Depth = 1024,
[switch] $AsHashtable,
[switch] $NoEnumerate
)
begin {
$ObjectBuffer = [System.Collections.ArrayList]::new()
}
process {
[void] $ObjectBuffer.Add($InputObject)
}
end {
# If our buffer only has one element in it we use this fast path. Otherwise the try{} catch{} block later will cause us to deserialize the object twice.
if ($ObjectBuffer.count -eq 1) {
$result = [JsonHelper]::Deserialize($ObjectBuffer[0], $depth)
}
# We want to support a user passing us two discrete json objects via the pipeline where we deserialize both. So we attempt to
# deserialize the first object and if it works we then deserialize each object as if it is its own json object.
else {
try {
[void] ([JsonHelper]::Deserialize($ObjectBuffer[0], $depth))
$Result = @(foreach ($item in $ObjectBuffer) {
[JsonHelper]::Deserialize($item, $depth)
})
} catch {
# If that fails we just take the whole input, concatenate it, and pass it to the parser.
$Result = [JsonHelper]::Deserialize([string]::join("`n",$ObjectBuffer.ToArray()), $depth)
}
}
# The noenumerate flag allows the returning of an array without unpacking it.
if ($NoEnumerate) {
# We have to force return an array otherwise powershell will collapse a one element array
if ($Result -is [array]) {
return @(,$result)
}
}
return $result
}
}
Function Invoke-RestMethodFast {
<#
.SYNOPSIS
Connects to a remote host and returns the content of the body casted to objects
.DESCRIPTION
Connects to a remote host and returns the content of the body casted to objects
.EXAMPLE
Invoke-RestMethodfast -Uri https://jsonplaceholder.typicode.com/todos/1
.NOTES
Supports any additional parameters that invoke-webrequest supports. Will only work with JSON, does not work with XML
#>
# Proxy all of the parameters to invoke-webrequest so that this can be a drop-in for invoke-restmethod
$params = $MyInvocation.UnboundArguments
$result = Invoke-WebRequest @params
ConvertFrom-JsonFast -InputObject $Result
}
Set-Alias -Name Invoke-FastRestMethod -Value Invoke-RestMethodFast
Set-Alias -Name ConvertFrom-FastJson -Value ConvertFrom-JsonFast
Export-ModuleMember -Function * -alias *