/
JsonSchemaYaml.cs
137 lines (120 loc) · 6.36 KB
/
JsonSchemaYaml.cs
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
//-----------------------------------------------------------------------
// <copyright file="SwaggerYamlDocument.cs" company="NSwag">
// Copyright (c) Rico Suter. All rights reserved.
// </copyright>
// <license>https://github.com/NSwag/NSwag/blob/master/LICENSE.md</license>
// <author>Rico Suter, mail@rsuter.com</author>
//-----------------------------------------------------------------------
using System;
using System.Dynamic;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using NJsonSchema.Generation;
using NJsonSchema.Infrastructure;
using NJsonSchema.References;
using YamlDotNet.Serialization;
namespace NJsonSchema.Yaml
{
/// <summary>Extension methods to load and save <see cref="JsonSchema4"/> from/to YAML.</summary>
public static class JsonSchemaYaml
{
/// <summary>Deserializes a JSON string to a <see cref="JsonSchema4" />.</summary>
/// <param name="data">The JSON string.</param>
/// <returns>The JSON Schema.</returns>
public static async Task<JsonSchema4> FromYamlAsync(string data)
{
return await JsonSchemaYaml.FromYamlAsync(data, null, CreateReferenceResolverFactory()).ConfigureAwait(false);
}
/// <summary>Deserializes a JSON string to a <see cref="JsonSchema4" />.</summary>
/// <param name="data">The JSON string.</param>
/// <param name="documentPath">The document path (URL or file path) for resolving relative document references.</param>
/// <returns>The JSON Schema.</returns>
public static async Task<JsonSchema4> FromYamlAsync(string data, string documentPath)
{
return await JsonSchemaYaml.FromYamlAsync(data, documentPath, CreateReferenceResolverFactory()).ConfigureAwait(false);
}
/// <summary>Deserializes a JSON string to a <see cref="JsonSchema4" />.</summary>
/// <param name="data">The JSON string.</param>
/// <param name="documentPath">The document path (URL or file path) for resolving relative document references.</param>
/// <param name="referenceResolverFactory">The JSON reference resolver factory.</param>
/// <returns>The JSON Schema.</returns>
public static async Task<JsonSchema4> FromYamlAsync(string data, string documentPath, Func<JsonSchema4, JsonReferenceResolver> referenceResolverFactory)
{
var deserializer = new DeserializerBuilder().Build();
var yamlObject = deserializer.Deserialize(new StringReader(data));
var serializer = new SerializerBuilder()
.JsonCompatible()
.Build();
var json = serializer.Serialize(yamlObject);
return await JsonSchema4.FromJsonAsync(json, documentPath, referenceResolverFactory).ConfigureAwait(false);
}
/// <summary>Converts the JSON Schema to YAML.</summary>
/// <returns>The YAML string.</returns>
public static string ToYaml(this JsonSchema4 document)
{
var json = document.ToJson();
var expConverter = new ExpandoObjectConverter();
dynamic deserializedObject = JsonConvert.DeserializeObject<ExpandoObject>(json, expConverter);
var serializer = new Serializer();
return serializer.Serialize(deserializedObject);
}
/// <summary>Creates a JSON Schema from a JSON file.</summary>
/// <param name="filePath">The file path.</param>
/// <returns>The <see cref="JsonSchema4" />.</returns>
public static async Task<JsonSchema4> FromFileAsync(string filePath)
{
return await FromFileAsync(filePath, CreateReferenceResolverFactory()).ConfigureAwait(false);
}
/// <summary>Creates a JSON Schema from a JSON file.</summary>
/// <param name="filePath">The file path.</param>
/// <param name="referenceResolverFactory">The JSON reference resolver factory.</param>
/// <returns>The <see cref="JsonSchema4" />.</returns>
public static async Task<JsonSchema4> FromFileAsync(string filePath, Func<JsonSchema4, JsonReferenceResolver> referenceResolverFactory)
{
var data = await DynamicApis.FileReadAllTextAsync(filePath).ConfigureAwait(false);
return await FromYamlAsync(data, filePath, referenceResolverFactory).ConfigureAwait(false);
}
/// <summary>Creates a JSON Schema from an URL.</summary>
/// <param name="url">The URL.</param>
/// <param name="referenceResolverFactory">The JSON reference resolver factory.</param>
/// <returns>The <see cref="JsonSchema4"/>.</returns>
public static async Task<JsonSchema4> FromUrlAsync(string url, Func<JsonSchema4, JsonReferenceResolver> referenceResolverFactory)
{
var data = await DynamicApis.HttpGetAsync(url).ConfigureAwait(false);
return await FromYamlAsync(data, url, referenceResolverFactory).ConfigureAwait(false);
}
private static string ConvertYamlToJson(string data)
{
var deserializer = new DeserializerBuilder().Build();
var yamlObject = deserializer.Deserialize(new StringReader(data));
var serializer = new SerializerBuilder()
.JsonCompatible()
.Build();
var json = serializer.Serialize(yamlObject);
return json;
}
private static Func<JsonSchema4, JsonReferenceResolver> CreateReferenceResolverFactory()
{
JsonReferenceResolver ReferenceResolverFactory(JsonSchema4 schema) =>
new JsonAndYamlReferenceResolver(new JsonSchemaResolver(schema, new JsonSchemaGeneratorSettings()));
return ReferenceResolverFactory;
}
private class JsonAndYamlReferenceResolver : JsonReferenceResolver
{
public JsonAndYamlReferenceResolver(JsonSchemaResolver schemaResolver)
: base(schemaResolver)
{
}
public override async Task<IJsonReference> ResolveFileReferenceAsync(string filePath)
{
return await FromFileAsync(filePath, schema => this).ConfigureAwait(false);
}
public override async Task<IJsonReference> ResolveUrlReferenceAsync(string url)
{
return await FromUrlAsync(url, schema => this).ConfigureAwait(false);
}
}
}
}