Comments (3)
Ok, spent some time on this, you can use a custom INodeDeserializer
to convert it into an array. I set the value to the Key
property on the object. Here's the code.
Note, it does not deserialize to the same yaml, if you need that, let me know and I could try and put something together for that.
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;
var yaml = @"name: ""Build""
on:
workflow_dispatch:
inputs:
reason:
description: The reason for the manual run
required: true
type: string
something_else:
description: Some other input
required: false
type: boolean
";
var deserializer = new DeserializerBuilder().WithNodeDeserializer(new InputObjectNodeDeserializer(), (syntax) => syntax.OnTop()).Build();
var action = deserializer.Deserialize<Actions>(yaml);
foreach (var input in action.On.WorkflowDispatch.Inputs)
{
Console.WriteLine("{0} - {1}", input.Key, input.Description);
}
public class Actions
{
[YamlMember(Alias = "name")]
public string Name { get; set; }
[YamlMember(Alias = "on")]
public Dispatch On { get; set; }
}
public class Dispatch
{
[YamlMember(Alias = "workflow_dispatch")]
public WorkflowDispatch WorkflowDispatch { get; set; }
}
public class WorkflowDispatch
{
[YamlMember(Alias = "inputs")]
public Input[] Inputs { get; set; }
}
public class Input
{
[YamlMember(Alias = "key")]
public string Key { get; set; }
[YamlMember(Alias = "description")]
public string Description { get; set; }
[YamlMember(Alias = "required")]
public bool Required { get; set; }
[YamlMember(Alias = "type")]
public string Type { get; set; }
}
public class InputObjectNodeDeserializer : INodeDeserializer
{
public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object?> nestedObjectDeserializer, out object? value)
{
if (expectedType != typeof(Input[]))
{
value = null;
return false;
}
if (!reader.Accept<MappingStart>())
{
value = null;
return false;
}
reader.Consume<MappingStart>();
var result = new List<Input>();
while (!reader.TryConsume<MappingEnd>(out var _))
{
var keyScalar = reader.Consume<Scalar>();
var input = nestedObjectDeserializer(reader, typeof(Input)) as Input;
if (input != null)
{
input.Key = keyScalar.Value;
}
result.Add(input);
}
value = result.ToArray();
return true;
}
}
The output
reason - The reason for the manual run
something_else - Some other input
I'm going to close this issue since this is an example of doing what you want, re-open if you need serialization too.
from yamldotnet.
The reasons it’s not coming in as an array is because it isn’t an array. It’s a mapping. Which means it will be properties or key/value pairs. You could probably create your own node deserializer or type converter to handle that part of your yaml differently.
You can see here what the different parts of your yaml are with this cool tool. It’s what we use to determine the validity of yaml and one of the tools we use to make sure we’re parsing things correctly.
http://ben-kiki.org/ypaste/data/78777/index.html
from yamldotnet.
I think the short answer to your question is "no" since arrays don't have string keys (like reason
) but you could make a type/named tuple that can hold the key and value from the mapping in one value.
It seems a lot easier to deserialize the way the library intends and then just implement a method on your type that returns the array-ified (key, value) pairs. I made a quick version with F#, but the C# version should be broadly similar. Except more verbose 😉.
Some gross F# code
#r "nuget: YamlDotNet"
open YamlDotNet.Serialization
open System.IO
type Input() =
member val description = "" with get, set
member val required = false with get, set
[<YamlMember(Alias = "type")>]
member val kind = "" with get, set
member z.toRecord =
{| description = z.description
required = z.required
kind = z.kind |}
type WorkflowDispatch() =
member val inputs: System.Collections.Generic.Dictionary<string, Input> =
System.Collections.Generic.Dictionary() with get, set
member z.inputsArray =
z.inputs.Keys
|> Seq.map (fun k ->
{| name = k
value = z.inputs[k].toRecord |})
|> Seq.toArray
type On() =
member val workflowDispatch = WorkflowDispatch() with get, set
type GHAction() =
member val name = "" with get, set
member val on = On() with get, set
member z.inputsArray = z.on.workflowDispatch.inputsArray
/// Create a deserializer for a YAML file
let deserializer _ =
DeserializerBuilder()
.WithNamingConvention(NamingConventions.UnderscoredNamingConvention.Instance)
.Build()
let deserialize<'t> (content: string) =
content |> (() |> deserializer).Deserialize<'t>
File.ReadAllText("ghaction.yml")
|> deserialize<GHAction>
|> (fun gha -> gha.inputsArray)
|> printfn "%A"
result:
[| { name = "reason"
value =
{ description = "The reason for the manual run"
kind = "string"
required = true } }
{ name = "something_else"
value =
{ description = "Some other input"
kind = "boolean"
required = false } } |]
from yamldotnet.
Related Issues (20)
- (Documentation) Unclear how to deserialize into objects HOT 4
- How can I know what value is not property
- Set anchor tag name during serialization using YamlDotNet? HOT 4
- Getting odd hash values in keys HOT 5
- `YamlStream.Load(TextReader)` interprets an empty value as an empty string instead of null. HOT 2
- Emitter doesn't handle comments between the mapping value and key HOT 1
- An exception occurs during Deserialize DateTimeOffset HOT 4
- How to have the `INamingConvention` passed into a custom value converter? HOT 3
- Parser does not recognize quoted keys HOT 2
- Can't handle anchored lists HOT 11
- Cannot parse YAML file, (Line: 2, Col: 3, Idx: 6) - (Line: 2, Col: 3, Idx: 6): Exception during deserialization HOT 2
- Do you think it's useful to add some F# examples along with the C# code? HOT 4
- Schema validation support HOT 10
- Unwanted conversion from a string to a numeric value HOT 1
- missing `IDeserializer object? Deserialize(string input)` method HOT 2
- How to Serialize an object with Directives, start and end marks (---, ...)? HOT 2
- YamlStream.Load with JSON with emojis (even escaped) fails: "While scanning a quoted scalar, found invalid Unicode character escape code." HOT 13
- OmitDefaults doesn't work for properties of sub-objects HOT 14
- Polymorphic deserialization - Alias $example_word cannot precede anchor declaration HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from yamldotnet.