From acb54caecc1051ac278cb4a553029a67d01e646e Mon Sep 17 00:00:00 2001 From: simonthum Date: Thu, 27 Jan 2022 14:25:48 +0100 Subject: [PATCH] Support duration as of JSON Schema 2019-09 (#1478) This should problably deperecate the time-span format specifier, but currently duration and time-span just coexist. Duration is the preferred output, as time-span was never formalized. --- .../CSharpTypeResolver.cs | 2 +- .../DataConversionGenerator.cs | 14 +++++++------- .../TypeScriptTypeResolver.cs | 8 ++++---- .../ValueGeneratorBase.cs | 1 + .../Generation/PrimitiveTypeGenerationTests.cs | 4 ++-- .../Generation/SampleJsonSchemaGeneratorTests.cs | 2 +- .../Generation/DefaultReflectionService.cs | 2 +- .../Generation/SampleJsonSchemaGenerator.cs | 4 ++-- src/NJsonSchema/JsonFormatStrings.cs | 5 ++++- 9 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs b/src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs index 764e9eaf4..eced21708 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs +++ b/src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs @@ -175,7 +175,7 @@ private string ResolveString(JsonSchema schema, bool isNullable, string typeName return isNullable && Settings.TimeType?.ToLowerInvariant() != "string" ? Settings.TimeType + "?" : Settings.TimeType; } - if (schema.Format == JsonFormatStrings.TimeSpan) + if (schema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return isNullable && Settings.TimeSpanType?.ToLowerInvariant() != "string" ? Settings.TimeSpanType + "?" : Settings.TimeSpanType; } diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/DataConversionGenerator.cs b/src/NJsonSchema.CodeGeneration.TypeScript/DataConversionGenerator.cs index f77375fa6..1177537ce 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript/DataConversionGenerator.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript/DataConversionGenerator.cs @@ -103,7 +103,7 @@ private static string GetStringToDateTime(DataConversionParameters parameters, J case TypeScriptDateTimeType.MomentJS: case TypeScriptDateTimeType.OffsetMomentJS: - if (typeSchema.Format == JsonFormatStrings.TimeSpan) + if (typeSchema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return "moment.duration"; } @@ -119,7 +119,7 @@ private static string GetStringToDateTime(DataConversionParameters parameters, J return ""; case TypeScriptDateTimeType.Luxon: - if (typeSchema.Format == JsonFormatStrings.TimeSpan) + if (typeSchema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return "Duration.fromISO"; } @@ -163,7 +163,7 @@ private static string GetDateTimeToString(DataConversionParameters parameters, J case TypeScriptDateTimeType.MomentJS: case TypeScriptDateTimeType.OffsetMomentJS: - if (typeSchema.Format == JsonFormatStrings.TimeSpan) + if (typeSchema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return "format('d.hh:mm:ss.SS', { trim: false })"; } @@ -181,7 +181,7 @@ private static string GetDateTimeToString(DataConversionParameters parameters, J return "toString()"; case TypeScriptDateTimeType.DayJS: - if (typeSchema.Format == JsonFormatStrings.TimeSpan) + if (typeSchema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return "format('d.hh:mm:ss.SSS')"; } @@ -208,7 +208,7 @@ private static bool IsDateTime(string format, TypeScriptDateTimeType type) return false; } - if (format == JsonFormatStrings.TimeSpan) + if (format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return false; } @@ -227,7 +227,7 @@ private static bool IsDateTime(string format, TypeScriptDateTimeType type) return true; } - if (format == JsonFormatStrings.TimeSpan) + if (format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return true; } @@ -244,7 +244,7 @@ private static bool IsDateTime(string format, TypeScriptDateTimeType type) return true; } - if (format == JsonFormatStrings.TimeSpan) + if (format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return true; } diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptTypeResolver.cs b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptTypeResolver.cs index 93ae216bd..301fd486a 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptTypeResolver.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptTypeResolver.cs @@ -213,7 +213,7 @@ private string ResolveString(JsonSchema schema, string typeNameHint) return "string"; } - if (schema.Format == JsonFormatStrings.TimeSpan) + if (schema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return "string"; } @@ -236,7 +236,7 @@ private string ResolveString(JsonSchema schema, string typeNameHint) return "moment.Moment"; } - if (schema.Format == JsonFormatStrings.TimeSpan) + if (schema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return "moment.Duration"; } @@ -258,7 +258,7 @@ private string ResolveString(JsonSchema schema, string typeNameHint) return "DateTime"; } - if (schema.Format == JsonFormatStrings.TimeSpan) + if (schema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return "Duration"; } @@ -280,7 +280,7 @@ private string ResolveString(JsonSchema schema, string typeNameHint) return "dayjs.Dayjs"; } - if (schema.Format == JsonFormatStrings.TimeSpan) + if (schema.Format is JsonFormatStrings.Duration or JsonFormatStrings.TimeSpan) { return "dayjs.Dayjs"; } diff --git a/src/NJsonSchema.CodeGeneration/ValueGeneratorBase.cs b/src/NJsonSchema.CodeGeneration/ValueGeneratorBase.cs index 6bb1f54b3..7adf36fe6 100644 --- a/src/NJsonSchema.CodeGeneration/ValueGeneratorBase.cs +++ b/src/NJsonSchema.CodeGeneration/ValueGeneratorBase.cs @@ -22,6 +22,7 @@ public abstract class ValueGeneratorBase JsonFormatStrings.Date, JsonFormatStrings.DateTime, JsonFormatStrings.Time, + JsonFormatStrings.Duration, JsonFormatStrings.TimeSpan, JsonFormatStrings.Uri, JsonFormatStrings.Guid, diff --git a/src/NJsonSchema.Tests/Generation/PrimitiveTypeGenerationTests.cs b/src/NJsonSchema.Tests/Generation/PrimitiveTypeGenerationTests.cs index 67a61424b..48bf741f3 100644 --- a/src/NJsonSchema.Tests/Generation/PrimitiveTypeGenerationTests.cs +++ b/src/NJsonSchema.Tests/Generation/PrimitiveTypeGenerationTests.cs @@ -71,7 +71,7 @@ public async Task When_property_is_timespan_then_schema_type_is_string() //// Assert Assert.Equal(JsonObjectType.String, schema.Properties["TimeSpan"].Type); - Assert.Equal(JsonFormatStrings.TimeSpan, schema.Properties["TimeSpan"].Format); + Assert.Equal(JsonFormatStrings.Duration, schema.Properties["TimeSpan"].Format); } [Fact] @@ -155,7 +155,7 @@ public async Task When_property_is_duration_then_schema_type_is_string() //// Assert Assert.Equal(JsonObjectType.String, schema.Properties["Duration"].Type); - Assert.Equal(JsonFormatStrings.TimeSpan, schema.Properties["Duration"].Format); + Assert.Equal(JsonFormatStrings.Duration, schema.Properties["Duration"].Format); } } } \ No newline at end of file diff --git a/src/NJsonSchema.Tests/Generation/SampleJsonSchemaGeneratorTests.cs b/src/NJsonSchema.Tests/Generation/SampleJsonSchemaGeneratorTests.cs index 1220ccd45..5aa6acd7e 100644 --- a/src/NJsonSchema.Tests/Generation/SampleJsonSchemaGeneratorTests.cs +++ b/src/NJsonSchema.Tests/Generation/SampleJsonSchemaGeneratorTests.cs @@ -35,7 +35,7 @@ public void PrimitiveProperties() Assert.Equal(JsonFormatStrings.DateTime, schema.Properties["datetime"].Format); Assert.Equal(JsonObjectType.String, schema.Properties["timespan"].Type); - Assert.Equal(JsonFormatStrings.TimeSpan, schema.Properties["timespan"].Format); + Assert.Equal(JsonFormatStrings.Duration, schema.Properties["timespan"].Format); } [Fact] diff --git a/src/NJsonSchema/Generation/DefaultReflectionService.cs b/src/NJsonSchema/Generation/DefaultReflectionService.cs index 3de36a2d0..afcd54cae 100644 --- a/src/NJsonSchema/Generation/DefaultReflectionService.cs +++ b/src/NJsonSchema/Generation/DefaultReflectionService.cs @@ -139,7 +139,7 @@ public virtual JsonTypeDescription GetDescription(ContextualType contextualType, if (type == typeof(TimeSpan) || type.FullName == "NodaTime.Duration") { - return JsonTypeDescription.Create(contextualType, JsonObjectType.String, false, JsonFormatStrings.TimeSpan); + return JsonTypeDescription.Create(contextualType, JsonObjectType.String, false, JsonFormatStrings.Duration); } if (type.FullName == "NodaTime.LocalDate" || diff --git a/src/NJsonSchema/Generation/SampleJsonSchemaGenerator.cs b/src/NJsonSchema/Generation/SampleJsonSchemaGenerator.cs index ee45247a5..46923309e 100644 --- a/src/NJsonSchema/Generation/SampleJsonSchemaGenerator.cs +++ b/src/NJsonSchema/Generation/SampleJsonSchemaGenerator.cs @@ -131,7 +131,7 @@ private void GenerateWithoutReference(JToken token, JsonSchema schema, JsonSchem case JTokenType.TimeSpan: schema.Type = JsonObjectType.String; - schema.Format = JsonFormatStrings.TimeSpan; + schema.Format = JsonFormatStrings.Duration; break; case JTokenType.Guid: @@ -157,7 +157,7 @@ private void GenerateWithoutReference(JToken token, JsonSchema schema, JsonSchem if (schema.Type == JsonObjectType.String && Regex.IsMatch(token.Value(), "^[0-9][0-9]:[0-9][0-9](:[0-9][0-9])?$")) { - schema.Format = JsonFormatStrings.TimeSpan; + schema.Format = JsonFormatStrings.Duration; } } diff --git a/src/NJsonSchema/JsonFormatStrings.cs b/src/NJsonSchema/JsonFormatStrings.cs index f73447a8f..bacad57be 100644 --- a/src/NJsonSchema/JsonFormatStrings.cs +++ b/src/NJsonSchema/JsonFormatStrings.cs @@ -16,9 +16,12 @@ public static class JsonFormatStrings /// Format for a . public const string DateTime = "date-time"; - /// Format for a . + /// Non-standard Format for a duration (time span). public const string TimeSpan = "time-span"; + /// Format for a duration (time span) as of 2019-09 . + public const string Duration = "duration"; + /// Format for an email. public const string Email = "email";