-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WiP] Implement deserializing to specific type #142
base: master
Are you sure you want to change the base?
[WiP] Implement deserializing to specific type #142
Conversation
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
Signed-off-by: Gabriel Adrian Samfira <[email protected]>
CC @iRon7 |
My knowledge of class Person {
[string]$Surname
[string]$Name
}
[Person]$deserialized.person |
In most languages you only concern yourself with attributes when serializing or deserializing. The goal is not to marshal the entire class with all private objects. The goal is to represent a yaml in a well defined structure. In Go for example this is done with structs and tags: type Person struct {
Surname string `json:"last-name"`
Name string `json:"first-name"`
} This struct (like powershell classes) can have methods attached, can have more complex types like other structs, etc. The nice thing about using classes is that you can define the type you want for each field with all the rules that each type comes with. But the above commandlet doesn't need to cast to a class necesarily. If all you need is a PSCustomObject you can just do: PS /> $yaml = @"
>> PsO:
>> field1: test
>> field2: anotherTest
>> dict:
>> hello: world
>> some-text: "just a string"
>> BigNr: 999999999999999999999999999999999999
>> person:
>> last-name: Samfira
>> first-name: Gabriel
>> "@
PS /> $res = ConvertFrom-YamlToClass -Yaml $yaml -Type ([pscustomobject])
PS /> $res.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
PS /> $res
PsO : {[field1, test], [field2, anotherTest]}
dict : {[hello, world]}
some-text : just a string
BigNr : 999999999999999999999999999999999999
person : {[last-name, Samfira], [first-name, Gabriel]}
PS /> |
I like the idea of having this in general. I needed this kind of stuff for Json serialization in C# multiple times in the past (also **Ignore-attributes). When working with serialization, you often need to tweak types, names and stuff. However, I personally have not used any class in thousands of PowerShell lines. In fact I thought about using classes in a recent PS project, but I skipped it because it did not work with the standard ConvertTo/From-Json serialization commands. I tend to use Json over Yaml. Only if there is no other way :-) |
@MODUSCarstenScholling fun fact, you can use powershell-yaml as a replacement for ConvertTo/From-Json 😄 . Json is a subset of yaml and is compatible. Thanks for the feedback! I appreciate it! |
This is a Work in progress. More of a proposal to get feedback. Commandlet names, design of how this is exposed, class names, etc are all subject to change. This is just to showcase an idea, nothing is set in stone.
This change adds a new commandlet called
ConvertFrom-YamlToClass
and a couple ofAttribute
s that can be used to decorate class properties.There are just 2 attributes for now:
PowerShellYamlPropertyAliasAttribute
- This can be used to map a yaml key to a class attribute, in case their names differ.PowerShellYamlSerializable
- to mark properties that powershell-yaml should recurse into, to attempt to resolve attribute overridesThis change also adds deserialization for PSCustomObjects and bigint. There are toggles for case insensitive deserialization among others, but currently we're just exploring the idea.
Example usage:
And the output is:
Things that don't yet work is keeping the original key names when serializing back to yaml/json, but this is something to be tackled if there's interest in this.