-
Notifications
You must be signed in to change notification settings - Fork 19
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
refactor: target netstandard #148
Changes from all commits
5419a1e
ca7b075
010e2dc
9f4c2f2
30559ef
aff12b7
76d7c22
d11fdfa
6ad314c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project> | ||
<!-- Common Properties used by all assemblies --> | ||
<PropertyGroup> | ||
VisualBean marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<LangVersion>10</LangVersion> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<ImplicitUsings>disable</ImplicitUsings> | ||
<Company>The LEGO Group</Company> | ||
<PackageProjectUrl>https://github.com/LEGO/AsyncAPI.NET</PackageProjectUrl> | ||
<PackageReadmeFile>README.md</PackageReadmeFile> | ||
<RepositoryUrl>https://github.com/LEGO/AsyncAPI.NET</RepositoryUrl> | ||
<PackageTags>asyncapi .net openapi documentation</PackageTags> | ||
</PropertyGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,15 +4,49 @@ namespace LEGO.AsyncAPI.Readers | |
{ | ||
using System; | ||
using System.Globalization; | ||
using System.IO; | ||
using System.Text.Encodings.Web; | ||
using System.Text.Json; | ||
using System.Text.Json.Nodes; | ||
using LEGO.AsyncAPI.Exceptions; | ||
|
||
/// <summary> | ||
/// Contains helper methods for working with Json | ||
/// </summary> | ||
internal static class JsonHelper | ||
{ | ||
public static string GetScalarValue(this JsonNode node) | ||
private static readonly JsonWriterOptions WriterOptions; | ||
|
||
static JsonHelper() | ||
{ | ||
WriterOptions = new JsonWriterOptions() | ||
{ | ||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, | ||
Indented = false, | ||
MaxDepth = 1, | ||
SkipValidation = true, | ||
}; | ||
} | ||
|
||
/// <summary> | ||
/// Takes a <see cref="JsonValue"/> and converts it into a string value. | ||
/// </summary> | ||
/// <param name="jsonValue">The node to convert.</param> | ||
/// <returns>The string value.</returns> | ||
public static string GetScalarValue(this JsonValue jsonValue) | ||
{ | ||
var scalarNode = node is JsonValue value ? value : throw new AsyncApiException($"Expected scalar value"); | ||
return Convert.ToString(scalarNode.GetValue<object>(), CultureInfo.InvariantCulture); | ||
using (MemoryStream memoryStream = new MemoryStream()) | ||
using (Utf8JsonWriter writer = new Utf8JsonWriter(memoryStream, WriterOptions)) | ||
{ | ||
jsonValue.WriteTo(writer); | ||
writer.Flush(); | ||
memoryStream.Position = 0; | ||
using (StreamReader reader = new StreamReader(memoryStream)) | ||
{ | ||
string value = reader.ReadToEnd(); | ||
return value.Trim('"'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The old method would not handle conversation of DateTime's correctly which was causing it to fail. Instead now we use the built in logic to serialization of values and then just remove the contain quotes. There are new unit tests that cover this logic |
||
} | ||
} | ||
} | ||
|
||
public static JsonNode ParseJsonString(string jsonString) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -196,7 +196,7 @@ public string GetReferencePointer() | |
return null; | ||
} | ||
|
||
return refNode.GetScalarValue(); | ||
return refNode.AsValue().GetScalarValue(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
} | ||
|
||
public string GetScalarValue(ValueNode key) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,22 +47,41 @@ public static JsonNode ToJsonNode(this YamlNode yaml) | |
}; | ||
} | ||
|
||
private static JsonValue ToJsonValue(this YamlScalarNode yaml) | ||
public static JsonValue ToJsonValue(this YamlScalarNode yaml) | ||
{ | ||
string value = yaml.Value; | ||
|
||
switch (yaml.Style) | ||
{ | ||
case ScalarStyle.Plain: | ||
return decimal.TryParse(yaml.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var d) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Decimal was ultimately chosen as double looses precision. double looses precision with certain conversions. |
||
? JsonValue.Create(d) | ||
: bool.TryParse(yaml.Value, out var b) | ||
? JsonValue.Create(b) | ||
: JsonValue.Create(yaml.Value)!; | ||
// We need to guess the types just based on it's format, so that means parsing | ||
if (int.TryParse(value, out int intValue)) | ||
{ | ||
return JsonValue.Create<int>(intValue); | ||
} | ||
|
||
if (double.TryParse(value, out double doubleValue)) | ||
{ | ||
return JsonValue.Create<double>(doubleValue); | ||
} | ||
|
||
if (DateTime.TryParse(value, out DateTime dateTimeValue)) | ||
{ | ||
return JsonValue.Create<DateTime>(dateTimeValue); | ||
} | ||
|
||
if (bool.TryParse(value, out bool boolValue)) | ||
{ | ||
return JsonValue.Create<bool>(boolValue); | ||
} | ||
|
||
return JsonValue.Create<string>(value); | ||
case ScalarStyle.SingleQuoted: | ||
case ScalarStyle.DoubleQuoted: | ||
case ScalarStyle.Literal: | ||
case ScalarStyle.Folded: | ||
case ScalarStyle.Any: | ||
return JsonValue.Create(yaml.Value); | ||
return JsonValue.Create<string>(yaml.Value); | ||
default: | ||
throw new ArgumentOutOfRangeException(); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,9 +5,12 @@ namespace LEGO.AsyncAPI.Writers | |
using System; | ||
using System.Globalization; | ||
using System.Linq; | ||
using System.Text.RegularExpressions; | ||
|
||
public static class SpecialCharacterStringExtensions | ||
{ | ||
private static readonly Regex numberRegex = new Regex("^[+-]?[0-9]*\\.?[0-9]*$", RegexOptions.Compiled, TimeSpan.FromSeconds(1)); | ||
|
||
// Plain style strings cannot start with indicators. | ||
// http://www.yaml.org/spec/1.2/spec.html#indicator// | ||
private static readonly char[] yamlIndicators = | ||
|
@@ -100,10 +103,15 @@ public static class SpecialCharacterStringExtensions | |
/// Escapes all special characters and put the string in quotes if necessary to | ||
/// get a YAML-compatible string. | ||
/// </summary> | ||
internal static string GetYamlCompatibleString(this string input) | ||
internal static string GetYamlCompatibleString(this string? input) | ||
{ | ||
if (input == null) | ||
{ | ||
return "null"; | ||
} | ||
|
||
// If string is an empty string, wrap it in quote to ensure it is not recognized as null. | ||
if (input == "") | ||
if (input.Length == 0) | ||
{ | ||
return "''"; | ||
} | ||
|
@@ -163,7 +171,7 @@ internal static string GetYamlCompatibleString(this string input) | |
input = input.Replace("\x1e", "\\x1e"); | ||
input = input.Replace("\x1f", "\\x1f"); | ||
|
||
return $"\"{input}\""; | ||
return $"'{input}'"; | ||
} | ||
|
||
// If string | ||
|
@@ -183,11 +191,25 @@ internal static string GetYamlCompatibleString(this string input) | |
return $"'{input}'"; | ||
} | ||
|
||
// If string can be mistaken as a number, a boolean, or a timestamp, | ||
// wrap it in quote to indicate that this is indeed a string, not a number, a boolean, or a timestamp | ||
if (decimal.TryParse(input, NumberStyles.Float, CultureInfo.InvariantCulture, out var _) || | ||
bool.TryParse(input, out var _) || | ||
DateTime.TryParse(input, out var _)) | ||
// Handle lexemes that can be intperated as as string | ||
// https://yaml.org/spec/1.2-old/spec.html#id2761292 | ||
switch (input.ToLower()) | ||
{ | ||
// Example 2.20. Floating Point | ||
case "-.inf": | ||
case ".inf": | ||
case ".nan": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These cases were all missed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good find! casesDecember 31, 2022 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might get caught by the forbidden combinations though. - dont remember off the top of my head. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be covered by the regex however just because I am not 100% sure let me add a test to explicitly check for that. |
||
// Example 2.21. Miscellaneous | ||
case "null": | ||
|
||
// Booleans | ||
case "true": | ||
case "false": | ||
return $"'{input}'"; | ||
} | ||
|
||
// Handle numbers | ||
if (numberRegex.IsMatch(input)) | ||
{ | ||
return $"'{input}'"; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets remove this.
We use stylecop, which enforces prefixing with 'this'