From 9d8791b5222a70b88aace73850c92e68629c5b59 Mon Sep 17 00:00:00 2001 From: Matthew Adams Date: Tue, 17 Dec 2024 10:03:34 +0000 Subject: [PATCH] Added support for projects that do not enable global usings. (#518) * Added support for projects that do not enable global usings --- README.md | 23 + .../CSharp/CSharpLanguageProvider.cs | 16 +- .../CSharp/CodeFileBuilders/ArrayPartial.cs | 9 + .../CSharp/CodeFileBuilders/BooleanPartial.cs | 9 + .../CSharp/CodeFileBuilders/CorePartial.cs | 9 + .../CSharp/CodeFileBuilders/NumberPartial.cs | 9 + .../CSharp/CodeFileBuilders/ObjectPartial.cs | 9 + .../CSharp/CodeFileBuilders/StringPartial.cs | 9 + .../CodeFileBuilders/ValidatePartial.cs | 9 + .../CSharp/TypeDeclarationExtensions.cs | 18 + .../GenerateCommand.cs | 8 +- .../GenerationDriver.cs | 3 +- .../Model/GeneratorConfig.Object.cs | 81 ++ .../Model/GeneratorConfig.Validate.cs | 23 +- .../generator-config.json | 4 + Solutions/Corvus.JsonSchema.sln | 6 + .../Model/TestModel.JsonStringArray.Array.cs | 835 +++++++++++++ .../TestModel.JsonStringArray.Validate.cs | 167 +++ .../Model/TestModel.JsonStringArray.cs | 679 +++++++++++ .../Model/TestModel.Object.cs | 1053 +++++++++++++++++ .../TestModel.SomeNumberEntity.Number.cs | 739 ++++++++++++ .../TestModel.SomeNumberEntity.Validate.cs | 193 +++ .../Model/TestModel.SomeNumberEntity.cs | 692 +++++++++++ .../TestModel.SomeStringEntity.String.cs | 529 +++++++++ .../TestModel.SomeStringEntity.Validate.cs | 171 +++ .../Model/TestModel.SomeStringEntity.cs | 688 +++++++++++ .../Model/TestModel.Validate.cs | 216 ++++ .../Sandbox.NoGlobalUsings/Model/TestModel.cs | 678 +++++++++++ Solutions/Sandbox.NoGlobalUsings/Program.cs | 7 + .../Sandbox.NoGlobalUsings.csproj | 39 + .../Sandbox.NoGlobalUsings/test-model.json | 24 + Solutions/generatetypes-release.ps1 | 4 +- Solutions/generatetypes.ps1 | 2 + 33 files changed, 6954 insertions(+), 7 deletions(-) create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.Array.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.Validate.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.Object.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.Number.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.Validate.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.String.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.Validate.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.Validate.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Model/TestModel.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Program.cs create mode 100644 Solutions/Sandbox.NoGlobalUsings/Sandbox.NoGlobalUsings.csproj create mode 100644 Solutions/Sandbox.NoGlobalUsings/test-model.json diff --git a/README.md b/README.md index a38654244..460852620 100644 --- a/README.md +++ b/README.md @@ -404,6 +404,29 @@ Benchmark suites for various components. The Source Generator which generates types from Json Schema. +## V4.1.2 Updates + +Added the `--addExplicitUsings` switch to the code generator (and a corresponding property to the `generator-config.json` schema). If `true`, then +the source generator will emit the standard global usings explicitly into the generated source files. You can then use the generated code in a project that does not have `enable`. + +```csharp +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +``` + +## V4.1.1 Updates + +## Help for people building analyzers and source generators with JSON Schema code generation + +We have built a self-contained package called Corvus.Json.SourceGeneratorTools for people looking to build .NET Analyzers or Source Generators that take advantage of JSON Schema code generation. + +See the [README](./Solutions/Corvus.Json.SourceGeneratorTools/README.md) for details. + ## V4.1 Updates ### YAML support diff --git a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CSharpLanguageProvider.cs b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CSharpLanguageProvider.cs index fc5cf049a..1f6b26e9a 100644 --- a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CSharpLanguageProvider.cs +++ b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CSharpLanguageProvider.cs @@ -594,6 +594,7 @@ public readonly struct Namespace(JsonReference baseUri, string dotnetNamespace) /// Gets the file extension to use. Defaults to .cs. /// If true, then the string conversion will be implicit. /// The line-end sequence. Defaults to \r\n. + /// If true, then the generated files will include using statements for the standard implicit usings. You should use this when your project does not use implicit usings. public class Options( string defaultNamespace, NamedType[]? namedTypes = null, @@ -604,7 +605,8 @@ public class Options( string[]? disabledNamingHeuristics = null, string fileExtension = ".cs", bool useImplicitOperatorString = false, - string lineEndSequence = "\r\n") + string lineEndSequence = "\r\n", + bool addExplicitUsings = false) { private readonly FrozenDictionary namedTypeMap = namedTypes?.ToFrozenDictionary(kvp => kvp.Reference, kvp => kvp) ?? FrozenDictionary.Empty; private readonly FrozenDictionary namespaceMap = namespaces?.ToFrozenDictionary(kvp => kvp.BaseUri, kvp => kvp.DotnetNamespace) ?? FrozenDictionary.Empty; @@ -625,7 +627,7 @@ public class Options( internal bool UseOptionalNameHeuristics { get; } = useOptionalNameHeuristics; /// - /// Gets a value indicating whether to always assert the format validation, regardless of the vocabularyy. + /// Gets a value indicating whether to always assert the format validation, regardless of the vocabulary. /// internal bool AlwaysAssertFormat { get; } = alwaysAssertFormat; @@ -640,7 +642,7 @@ public class Options( internal string FileExtension { get; } = fileExtension; /// - /// Gets a value indicating whether to generate an implict operator for conversion to . + /// Gets a value indicating whether to generate an implicit operator for conversion to . /// internal bool UseImplicitOperatorString { get; } = useImplicitOperatorString; @@ -654,6 +656,14 @@ public class Options( /// internal HashSet DisabledNamingHeuristics { get; } = disabledNamingHeuristics is string[] n ? [.. n] : []; + /// + /// Gets a value indicating whether to include using statements for the standard implicit usings. + /// + /// + /// You should use this when your project does not use implicit usings. + /// + internal bool AddExplicitUsings { get; } = addExplicitUsings; + /// /// Gets the namespace for the base URI. /// diff --git a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ArrayPartial.cs b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ArrayPartial.cs index b57a46234..27710aeec 100644 --- a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ArrayPartial.cs +++ b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ArrayPartial.cs @@ -25,6 +25,8 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla { if ((typeDeclaration.ImpliedCoreTypes() & CoreTypes.Array) != 0) { + FrameworkType addExplicitUsings = typeDeclaration.AddExplicitUsings() ? FrameworkType.All : FrameworkType.NotEmitted; + generator .BeginFile(typeDeclaration, "Array") .AppendAutoGeneratedHeader() @@ -32,6 +34,13 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla .AppendLine("#nullable enable") .AppendLine() .AppendUsings( + new("global::System", addExplicitUsings), + new("global::System.Collections.Generic", addExplicitUsings), + new("global::System.IO", addExplicitUsings), + new("global::System.Linq", addExplicitUsings), + new("global::System.Net.Http", addExplicitUsings), + new("global::System.Threading", addExplicitUsings), + new("global::System.Threading.Tasks", addExplicitUsings), new("System.Buffers", FrameworkType.Net80OrGreater), "System.Collections", "System.Collections.Immutable", diff --git a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/BooleanPartial.cs b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/BooleanPartial.cs index 52eb7bd28..aa9a0424b 100644 --- a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/BooleanPartial.cs +++ b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/BooleanPartial.cs @@ -25,6 +25,8 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla { if ((typeDeclaration.ImpliedCoreTypes() & CoreTypes.Boolean) != 0) { + FrameworkType addExplicitUsings = typeDeclaration.AddExplicitUsings() ? FrameworkType.All : FrameworkType.NotEmitted; + generator .BeginFile(typeDeclaration, "Boolean") .AppendAutoGeneratedHeader() @@ -32,6 +34,13 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla .AppendLine("#nullable enable") .AppendLine() .AppendUsings( + new("global::System", addExplicitUsings), + new("global::System.Collections.Generic", addExplicitUsings), + new("global::System.IO", addExplicitUsings), + new("global::System.Linq", addExplicitUsings), + new("global::System.Net.Http", addExplicitUsings), + new("global::System.Threading", addExplicitUsings), + new("global::System.Threading.Tasks", addExplicitUsings), new("System.Collections.Immutable", EmitIfIsObjectOrArray(typeDeclaration)), "System.Diagnostics.CodeAnalysis", "System.Text.Json", diff --git a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/CorePartial.cs b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/CorePartial.cs index 126a121b4..2c7ed34bd 100644 --- a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/CorePartial.cs +++ b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/CorePartial.cs @@ -21,6 +21,8 @@ private CorePartial() /// public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDeclaration) { + FrameworkType addExplicitUsings = typeDeclaration.AddExplicitUsings() ? FrameworkType.All : FrameworkType.NotEmitted; + return generator .BeginFile(typeDeclaration, string.Empty) .AppendAutoGeneratedHeader() @@ -28,6 +30,13 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla .AppendLine("#nullable enable") .AppendLine() .AppendUsings( + new("global::System", addExplicitUsings), + new("global::System.Collections.Generic", addExplicitUsings), + new("global::System.IO", addExplicitUsings), + new("global::System.Linq", addExplicitUsings), + new("global::System.Net.Http", addExplicitUsings), + new("global::System.Threading", addExplicitUsings), + new("global::System.Threading.Tasks", addExplicitUsings), "System.Buffers", RequiresImmutableCollections(typeDeclaration) ? "System.Collections.Immutable" : ConditionalCodeSpecification.DoNotEmit, "System.Runtime.CompilerServices", diff --git a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/NumberPartial.cs b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/NumberPartial.cs index e64b43ff4..efc2a9767 100644 --- a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/NumberPartial.cs +++ b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/NumberPartial.cs @@ -25,6 +25,8 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla { if ((typeDeclaration.ImpliedCoreTypes() & (CoreTypes.Number | CoreTypes.Integer)) != 0) { + FrameworkType addExplicitUsings = typeDeclaration.AddExplicitUsings() ? FrameworkType.All : FrameworkType.NotEmitted; + generator .BeginFile(typeDeclaration, "Number") .AppendAutoGeneratedHeader() @@ -32,6 +34,13 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla .AppendLine("#nullable enable") .AppendLine() .AppendUsings( + new("global::System", addExplicitUsings), + new("global::System.Collections.Generic", addExplicitUsings), + new("global::System.IO", addExplicitUsings), + new("global::System.Linq", addExplicitUsings), + new("global::System.Net.Http", addExplicitUsings), + new("global::System.Threading", addExplicitUsings), + new("global::System.Threading.Tasks", addExplicitUsings), new("System.Collections.Immutable", EmitIfIsObjectOrArray(typeDeclaration)), "System.Diagnostics.CodeAnalysis", new("System.Numerics", FrameworkType.Net80OrGreater), diff --git a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ObjectPartial.cs b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ObjectPartial.cs index 063da8df9..ab797b8ec 100644 --- a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ObjectPartial.cs +++ b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ObjectPartial.cs @@ -25,6 +25,8 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla { if ((typeDeclaration.ImpliedCoreTypes() & CoreTypes.Object) != 0) { + FrameworkType addExplicitUsings = typeDeclaration.AddExplicitUsings() ? FrameworkType.All : FrameworkType.NotEmitted; + generator .BeginFile(typeDeclaration, "Object") .AppendAutoGeneratedHeader() @@ -32,6 +34,13 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla .AppendLine("#nullable enable") .AppendLine() .AppendUsings( + new("global::System", addExplicitUsings), + new("global::System.Collections.Generic", addExplicitUsings), + new("global::System.IO", addExplicitUsings), + new("global::System.Linq", addExplicitUsings), + new("global::System.Net.Http", addExplicitUsings), + new("global::System.Threading", addExplicitUsings), + new("global::System.Threading.Tasks", addExplicitUsings), new("System.Collections", EmitIfIsMapObject(typeDeclaration)), "System.Collections.Immutable", new("System.Diagnostics.CodeAnalysis", EmitIfIsMapObject(typeDeclaration)), diff --git a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/StringPartial.cs b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/StringPartial.cs index 1789558f4..523ab7476 100644 --- a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/StringPartial.cs +++ b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/StringPartial.cs @@ -25,6 +25,8 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla { if ((typeDeclaration.ImpliedCoreTypes() & CoreTypes.String) != 0) { + FrameworkType addExplicitUsings = typeDeclaration.AddExplicitUsings() ? FrameworkType.All : FrameworkType.NotEmitted; + generator .BeginFile(typeDeclaration, "String") .AppendAutoGeneratedHeader() @@ -32,6 +34,13 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla .AppendLine("#nullable enable") .AppendLine() .AppendUsings( + new("global::System", addExplicitUsings), + new("global::System.Collections.Generic", addExplicitUsings), + new("global::System.IO", addExplicitUsings), + new("global::System.Linq", addExplicitUsings), + new("global::System.Net.Http", addExplicitUsings), + new("global::System.Threading", addExplicitUsings), + new("global::System.Threading.Tasks", addExplicitUsings), "System.Buffers", new("System.Collections.Immutable", EmitIfIsObjectOrArray(typeDeclaration)), "System.Diagnostics.CodeAnalysis", diff --git a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ValidatePartial.cs b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ValidatePartial.cs index 01cae4f6e..36f6fec07 100644 --- a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ValidatePartial.cs +++ b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/CodeFileBuilders/ValidatePartial.cs @@ -24,6 +24,8 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla // If we have any validation keywords, emit the validation file. if (typeDeclaration.ValidationKeywords().Count != 0) { + FrameworkType addExplicitUsings = typeDeclaration.AddExplicitUsings() ? FrameworkType.All : FrameworkType.NotEmitted; + generator .BeginFile(typeDeclaration, "Validate") .AppendAutoGeneratedHeader() @@ -31,6 +33,13 @@ public CodeGenerator EmitFile(CodeGenerator generator, TypeDeclaration typeDecla .AppendLine("#nullable enable") .AppendLine() .AppendUsings( + new("global::System", addExplicitUsings), + new("global::System.Collections.Generic", addExplicitUsings), + new("global::System.IO", addExplicitUsings), + new("global::System.Linq", addExplicitUsings), + new("global::System.Net.Http", addExplicitUsings), + new("global::System.Threading", addExplicitUsings), + new("global::System.Threading.Tasks", addExplicitUsings), "System.Runtime.CompilerServices", "System.Text.Json", RequiresRegularExressions(typeDeclaration) ? "System.Text.RegularExpressions" : ConditionalCodeSpecification.DoNotEmit, diff --git a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/TypeDeclarationExtensions.cs b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/TypeDeclarationExtensions.cs index a67dc34a2..712fcfe04 100644 --- a/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/TypeDeclarationExtensions.cs +++ b/Solutions/Corvus.Json.CodeGeneration.CSharp/Corvus.Json.CodeGeneration/CSharp/TypeDeclarationExtensions.cs @@ -23,6 +23,7 @@ public static class TypeDeclarationExtensions private const string OptionalAsNullableKey = "CSharp_LanguageProvider_OptionalAsNullable"; private const string PreferredBinaryJsonNumberKindKey = "CSharp_LanguageProvider_PreferredBinaryJsonNumberKind"; private const string UseImplicitOperatorStringKey = "CSharp_LanguageProvider_UseImplicitOperatorString"; + private const string AddExplicitUsingsKey = "CSharp_LanguageProvider_AddExplicitUsings"; /// /// Sets the relevant metadata from the . @@ -34,6 +35,7 @@ public static void SetCSharpOptions(this TypeDeclaration typeDeclaration, CSharp typeDeclaration.SetMetadata(AlwaysAssertFormatKey, options.AlwaysAssertFormat); typeDeclaration.SetMetadata(OptionalAsNullableKey, options.OptionalAsNullable); typeDeclaration.SetMetadata(UseImplicitOperatorStringKey, options.UseImplicitOperatorString); + typeDeclaration.SetMetadata(AddExplicitUsingsKey, options.AddExplicitUsings); } /// @@ -180,6 +182,22 @@ public static bool UseImplicitOperatorString(this TypeDeclaration typeDeclaratio return false; } + /// + /// Gets a value indicating whether to generate using statements for the standard implicit usings. + /// + /// The type declaration to test. + /// if the using statements should be added. + public static bool AddExplicitUsings(this TypeDeclaration typeDeclaration) + { + if (typeDeclaration.TryGetMetadata(AddExplicitUsingsKey, out bool? addExplicitUsings) && + addExplicitUsings is bool value) + { + return value; + } + + return false; + } + /// /// Determines if the given name collides with the parent name. /// diff --git a/Solutions/Corvus.Json.CodeGenerator/GenerateCommand.cs b/Solutions/Corvus.Json.CodeGenerator/GenerateCommand.cs index 86c15fda4..31a87f557 100644 --- a/Solutions/Corvus.Json.CodeGenerator/GenerateCommand.cs +++ b/Solutions/Corvus.Json.CodeGenerator/GenerateCommand.cs @@ -84,6 +84,11 @@ public sealed class Settings : CommandSettings [Description("If true, YAML support is enabled. You may use YAML, JSON or a mixture of such documents.")] [DefaultValue(false)] public bool SupportYaml { get; init; } + + [CommandOption("--addExplicitUsings")] + [Description("If true, the generate will include using statements for the standard implicit usings.")] + [DefaultValue(false)] + public bool AddExplicitUsings { get; init; } } /// @@ -109,7 +114,8 @@ public override Task ExecuteAsync(CommandContext context, Settings settings useSchemaValue: settings.UseSchema != SchemaVariant.NotSpecified ? (GeneratorConfig.UseSchema)settings.UseSchema.ToString() : default(GeneratorConfig.UseSchema?), useImplicitOperatorString: settings.UseImplicitOperatorString, useUnixLineEndings: settings.UseUnixLineEndings, - supportYaml: settings.SupportYaml); + supportYaml: settings.SupportYaml, + addExplicitUsings: settings.AddExplicitUsings); return GenerationDriver.GenerateTypes(config); } diff --git a/Solutions/Corvus.Json.CodeGenerator/GenerationDriver.cs b/Solutions/Corvus.Json.CodeGenerator/GenerationDriver.cs index 8484993f5..83717d35f 100644 --- a/Solutions/Corvus.Json.CodeGenerator/GenerationDriver.cs +++ b/Solutions/Corvus.Json.CodeGenerator/GenerationDriver.cs @@ -204,7 +204,8 @@ private static CSharpLanguageProvider.Options MapGeneratorConfigToOptions(in Gen optionalAsNullable: (generatorConfig.OptionalAsNullableValue ?? GeneratorConfig.OptionalAsNullable.DefaultInstance).Equals(GeneratorConfig.OptionalAsNullable.EnumValues.NullOrUndefined), disabledNamingHeuristics: generatorConfig.DisabledNamingHeuristics?.Select(n => (string)n).ToArray(), useImplicitOperatorString: generatorConfig.UseImplicitOperatorString ?? false, - lineEndSequence: (generatorConfig.UseUnixLineEndings ?? false) ? "\n" : "\r\n"); + lineEndSequence: (generatorConfig.UseUnixLineEndings ?? false) ? "\n" : "\r\n", + addExplicitUsings: generatorConfig.AddExplicitUsings ?? false); } private static async Task BeginMapFile(GeneratorConfig generatorConfig, string outputPath) diff --git a/Solutions/Corvus.Json.CodeGenerator/Model/GeneratorConfig.Object.cs b/Solutions/Corvus.Json.CodeGenerator/Model/GeneratorConfig.Object.cs index e17d8db2a..82bf44316 100644 --- a/Solutions/Corvus.Json.CodeGenerator/Model/GeneratorConfig.Object.cs +++ b/Solutions/Corvus.Json.CodeGenerator/Model/GeneratorConfig.Object.cs @@ -100,6 +100,56 @@ public int Count } } + /// + /// Gets the (optional) addExplicitUsings property. + /// + /// + /// + /// If this JSON property is then the value returned will be . + /// + /// + /// If true, then the generated files will include using statements for the standard implicit usings. You should use this when your project does not use implicit usings. + /// + /// + public Corvus.Json.JsonBoolean? AddExplicitUsings + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + return default; + } + + if (this.jsonElementBacking.TryGetProperty(JsonPropertyNames.AddExplicitUsingsUtf8, out JsonElement result)) + { + if (result.ValueKind == JsonValueKind.Null || result.ValueKind == JsonValueKind.Undefined) + { + return default; + } + + return new(result); + } + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(JsonPropertyNames.AddExplicitUsings, out JsonAny result)) + { + if (result.IsNullOrUndefined()) + { + return default; + } + + return result.As(); + } + } + + return default; + } + } + /// /// Gets the (optional) additionalFiles property. /// @@ -867,6 +917,7 @@ public static GeneratorConfig FromProperties(ImmutableList s public static GeneratorConfig Create( in Corvus.Json.JsonString rootNamespace, in Corvus.Json.CodeGenerator.GeneratorConfig.GenerationSpecifications typesToGenerate, + in Corvus.Json.JsonBoolean? addExplicitUsings = null, in Corvus.Json.CodeGenerator.GeneratorConfig.FileList? additionalFiles = null, in Corvus.Json.JsonBoolean? assertFormat = null, in Corvus.Json.CodeGenerator.GeneratorConfig.JsonStringArray? disabledNamingHeuristics = null, @@ -885,6 +936,11 @@ public static GeneratorConfig Create( builder.Add(JsonPropertyNames.RootNamespace, rootNamespace.AsAny); builder.Add(JsonPropertyNames.TypesToGenerate, typesToGenerate.AsAny); + if (addExplicitUsings is not null) + { + builder.Add(JsonPropertyNames.AddExplicitUsings, addExplicitUsings.Value.AsAny); + } + if (additionalFiles is not null) { builder.Add(JsonPropertyNames.AdditionalFiles, additionalFiles.Value.AsAny); @@ -1061,6 +1117,21 @@ public bool HasProperty(ReadOnlySpan name) throw new InvalidOperationException(); } + /// + /// Sets the (optional) addExplicitUsings property. + /// + /// The new property value + /// The instance with the property set. + /// + /// + /// If true, then the generated files will include using statements for the standard implicit usings. You should use this when your project does not use implicit usings. + /// + /// + public GeneratorConfig WithAddExplicitUsings(in Corvus.Json.JsonBoolean? value) + { + return value.HasValue ? this.SetProperty(JsonPropertyNames.AddExplicitUsings, value.Value) : this.RemoveProperty(JsonPropertyNames.AddExplicitUsings); + } + /// /// Sets the (optional) additionalFiles property. /// @@ -1683,6 +1754,11 @@ public GeneratorConfig RemoveProperty(ReadOnlySpan name) /// public static class JsonPropertyNames { + /// + /// Gets the JSON property name for . + /// + public const string AddExplicitUsings = "addExplicitUsings"; + /// /// Gets the JSON property name for . /// @@ -1758,6 +1834,11 @@ public static class JsonPropertyNames /// public const string UseUnixLineEndings = "useUnixLineEndings"; + /// + /// Gets the JSON property name for . + /// + public static ReadOnlySpan AddExplicitUsingsUtf8 => "addExplicitUsings"u8; + /// /// Gets the JSON property name for . /// diff --git a/Solutions/Corvus.Json.CodeGenerator/Model/GeneratorConfig.Validate.cs b/Solutions/Corvus.Json.CodeGenerator/Model/GeneratorConfig.Validate.cs index e03ce89f6..f560c5e7a 100644 --- a/Solutions/Corvus.Json.CodeGenerator/Model/GeneratorConfig.Validate.cs +++ b/Solutions/Corvus.Json.CodeGenerator/Model/GeneratorConfig.Validate.cs @@ -119,7 +119,28 @@ internal static ValidationContext ObjectValidationHandler( int propertyCount = 0; foreach (JsonObjectProperty property in value.EnumerateObject()) { - if (property.NameEquals(JsonPropertyNames.AdditionalFilesUtf8, JsonPropertyNames.AdditionalFiles)) + if (property.NameEquals(JsonPropertyNames.AddExplicitUsingsUtf8, JsonPropertyNames.AddExplicitUsings)) + { + result = result.WithLocalProperty(propertyCount); + if (level > ValidationLevel.Basic) + { + result = result.PushValidationLocationReducedPathModifierAndProperty(new("#/properties/addExplicitUsings"), JsonPropertyNames.AddExplicitUsings); + } + + ValidationContext propertyResult = property.Value.As().Validate(result.CreateChildContext(), level); + if (level == ValidationLevel.Flag && !propertyResult.IsValid) + { + return propertyResult; + } + + result = result.MergeResults(propertyResult.IsValid, level, propertyResult); + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + } + else if (property.NameEquals(JsonPropertyNames.AdditionalFilesUtf8, JsonPropertyNames.AdditionalFiles)) { result = result.WithLocalProperty(propertyCount); if (level > ValidationLevel.Basic) diff --git a/Solutions/Corvus.Json.CodeGenerator/generator-config.json b/Solutions/Corvus.Json.CodeGenerator/generator-config.json index 187f11249..3c10582cd 100644 --- a/Solutions/Corvus.Json.CodeGenerator/generator-config.json +++ b/Solutions/Corvus.Json.CodeGenerator/generator-config.json @@ -62,6 +62,10 @@ "supportYaml": { "type": "boolean", "description": "If true, YAML support is enabled. You may use YAML, JSON or a mixture of such documents." + }, + "addExplicitUsings": { + "type": "boolean", + "description": "If true, then the generated files will include using statements for the standard implicit usings. You should use this when your project does not use implicit usings." } }, "$defs": { diff --git a/Solutions/Corvus.JsonSchema.sln b/Solutions/Corvus.JsonSchema.sln index 7241ec2de..fd8655ac7 100644 --- a/Solutions/Corvus.JsonSchema.sln +++ b/Solutions/Corvus.JsonSchema.sln @@ -69,6 +69,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox.SourceGenerator", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Corvus.Json.SourceGeneratorTools", "Corvus.Json.SourceGeneratorTools\Corvus.Json.SourceGeneratorTools.csproj", "{A7D7CAA6-0747-4CE4-9E7D-EB649C1B4246}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox.NoGlobalUsings", "Sandbox.NoGlobalUsings\Sandbox.NoGlobalUsings.csproj", "{6D9F3F39-45E2-4B3A-821D-1073064812A9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -207,6 +209,10 @@ Global {A7D7CAA6-0747-4CE4-9E7D-EB649C1B4246}.Debug|Any CPU.Build.0 = Debug|Any CPU {A7D7CAA6-0747-4CE4-9E7D-EB649C1B4246}.Release|Any CPU.ActiveCfg = Release|Any CPU {A7D7CAA6-0747-4CE4-9E7D-EB649C1B4246}.Release|Any CPU.Build.0 = Release|Any CPU + {6D9F3F39-45E2-4B3A-821D-1073064812A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6D9F3F39-45E2-4B3A-821D-1073064812A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6D9F3F39-45E2-4B3A-821D-1073064812A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D9F3F39-45E2-4B3A-821D-1073064812A9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.Array.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.Array.cs new file mode 100644 index 000000000..4779ac64e --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.Array.cs @@ -0,0 +1,835 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; + +#if NET8_0_OR_GREATER +using System.Buffers; +#endif +using System.Collections; +using System.Collections.Immutable; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Corvus.Json; +using Corvus.Json.Internal; + +namespace Sandbox; + +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + /// Generated from JSON Schema. + /// +#if NET8_0_OR_GREATER + [CollectionBuilder(typeof(JsonStringArray), "Create")] +#endif + public readonly partial struct JsonStringArray + : IJsonArray, + IReadOnlyCollection + { + /// + /// Gets an empty array. + /// + public static JsonStringArray EmptyArray { get; } = From(ImmutableList.Empty); + + /// + /// Gets the rank of the array. + /// + public static int Rank => 1; + + /// + Corvus.Json.JsonAny IJsonArray.this[int index] + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (index < 0) + { + throw new IndexOutOfRangeException(); + } + + JsonElement.ArrayEnumerator enumerator = this.jsonElementBacking.EnumerateArray(); + while (index >= 0) + { + index--; + if (!enumerator.MoveNext()) + { + throw new IndexOutOfRangeException(); + } + } + + return new(enumerator.Current); + } + + if ((this.backing & Backing.Array) != 0) + { + try + { + return this.arrayBacking[index]; + } + catch (ArgumentOutOfRangeException ex) + { + throw new IndexOutOfRangeException(ex.Message, ex); + } + } + + throw new InvalidOperationException(); + } + } + + /// + /// Gets the item at the given index. + /// + /// The index at which to retrieve the item. + /// The item at the given index. + /// The index was outside the bounds of the array. + /// The value is not an array. + public Corvus.Json.JsonString this[int index] + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (index < 0) + { + throw new IndexOutOfRangeException(); + } + + JsonElement.ArrayEnumerator enumerator = this.jsonElementBacking.EnumerateArray(); + while (index >= 0) + { + index--; + if (!enumerator.MoveNext()) + { + throw new IndexOutOfRangeException(); + } + } + + return new(enumerator.Current); + } + + if ((this.backing & Backing.Array) != 0) + { + try + { + return this.arrayBacking[index].As(); + } + catch (ArgumentOutOfRangeException ex) + { + throw new IndexOutOfRangeException(ex.Message, ex); + } + } + + throw new InvalidOperationException(); + } + } + + /// + /// Conversion from . + /// + /// The value from which to convert. + public static implicit operator JsonStringArray(ImmutableList value) + { + return new(value); + } + + /// + /// Conversion to . + /// + /// The value from which to convert. + public static implicit operator ImmutableList(JsonStringArray value) + { + return + __CorvusArrayHelpers.GetImmutableList(value); + } + + /// + /// Conversion from JsonArray. + /// + /// The value from which to convert. + public static implicit operator JsonStringArray(JsonArray value) + { + if (value.HasDotnetBacking && value.ValueKind == JsonValueKind.Array) + { + return new( + value.AsImmutableList()); + } + + return new(value.AsJsonElement); + } + + /// + /// Conversion to JsonArray. + /// + /// The value from which to convert. + public static implicit operator JsonArray(JsonStringArray value) + { + return + value.AsArray; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The list of items from which to construct the array. + /// An instance of the array constructed from the list. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static JsonStringArray From(ImmutableList items) + { + return new(items); + } + + /// + /// Create an new instance of the " struct from a span of items. + /// + /// The span of items from which to construct the array. + /// An instance of the array constructed from the span. + public static JsonStringArray Create(ReadOnlySpan items) + { + return new([..items]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + /// An instance of the array constructed from the value. + public static JsonStringArray FromItems(params Corvus.Json.JsonString[] items) + { + return new([..items]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The 1st item in the array. + /// An instance of the array constructed from the values. + public static JsonStringArray FromItems(in Corvus.Json.JsonString item1) + { + return new([item1.AsAny]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The 1st item in the array. + /// The 2nd item in the array. + /// An instance of the array constructed from the values. + public static JsonStringArray FromItems(in Corvus.Json.JsonString item1, in Corvus.Json.JsonString item2) + { + return new([item1.AsAny, item2.AsAny]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The 1st item in the array. + /// The 2nd item in the array. + /// The 3rd item in the array. + /// An instance of the array constructed from the values. + public static JsonStringArray FromItems(in Corvus.Json.JsonString item1, in Corvus.Json.JsonString item2, in Corvus.Json.JsonString item3) + { + return new([item1.AsAny, item2.AsAny, item3.AsAny]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The 1st item in the array. + /// The 2nd item in the array. + /// The 3rd item in the array. + /// The 4th item in the array. + /// An instance of the array constructed from the values. + public static JsonStringArray FromItems(in Corvus.Json.JsonString item1, in Corvus.Json.JsonString item2, in Corvus.Json.JsonString item3, in Corvus.Json.JsonString item4) + { + return new([item1.AsAny, item2.AsAny, item3.AsAny, item4.AsAny]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The 1st item in the array. + /// The 2nd item in the array. + /// The 3rd item in the array. + /// The 4th item in the array. + /// The 5th item in the array. + /// An instance of the array constructed from the values. + public static JsonStringArray FromItems(in Corvus.Json.JsonString item1, in Corvus.Json.JsonString item2, in Corvus.Json.JsonString item3, in Corvus.Json.JsonString item4, in Corvus.Json.JsonString item5) + { + return new([item1.AsAny, item2.AsAny, item3.AsAny, item4.AsAny, item5.AsAny]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The 1st item in the array. + /// The 2nd item in the array. + /// The 3rd item in the array. + /// The 4th item in the array. + /// The 5th item in the array. + /// The 6th item in the array. + /// An instance of the array constructed from the values. + public static JsonStringArray FromItems(in Corvus.Json.JsonString item1, in Corvus.Json.JsonString item2, in Corvus.Json.JsonString item3, in Corvus.Json.JsonString item4, in Corvus.Json.JsonString item5, in Corvus.Json.JsonString item6) + { + return new([item1.AsAny, item2.AsAny, item3.AsAny, item4.AsAny, item5.AsAny, item6.AsAny]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The 1st item in the array. + /// The 2nd item in the array. + /// The 3rd item in the array. + /// The 4th item in the array. + /// The 5th item in the array. + /// The 6th item in the array. + /// The 7th item in the array. + /// An instance of the array constructed from the values. + public static JsonStringArray FromItems(in Corvus.Json.JsonString item1, in Corvus.Json.JsonString item2, in Corvus.Json.JsonString item3, in Corvus.Json.JsonString item4, in Corvus.Json.JsonString item5, in Corvus.Json.JsonString item6, in Corvus.Json.JsonString item7) + { + return new([item1.AsAny, item2.AsAny, item3.AsAny, item4.AsAny, item5.AsAny, item6.AsAny, item7.AsAny]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The items from which to construct the instance. + /// An instance of the array constructed from the items. + public static JsonStringArray FromRange(IEnumerable items) + { + return new([..items]); + } + +#if NET8_0_OR_GREATER + /// + /// Initializes a new instance of the struct. + /// + /// The items from which to construct the instance. + /// An instance of the array constructed from the items . + static JsonStringArray IJsonArray.FromRange(IEnumerable items) + { + return new([..items]); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The type of the items to add. + /// The items from which to construct the instance. + /// An instance of the array constructed from the items. + static JsonStringArray IJsonArray.FromRange(IEnumerable items) + { + return new([..items.Select(item => item.AsAny)]); + } +#endif + + /// + IEnumerator IEnumerable.GetEnumerator() => this.EnumerateArray(); + + /// + IEnumerator IEnumerable.GetEnumerator() => this.EnumerateArray(); + + /// + int IReadOnlyCollection.Count => this.GetArrayLength(); + + /// + public ImmutableList AsImmutableList() + { + return __CorvusArrayHelpers.GetImmutableList(this); + } + + /// + public ImmutableList.Builder AsImmutableListBuilder() + { + return __CorvusArrayHelpers.GetImmutableListBuilder(this); + } + + /// + public int GetArrayLength() + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.GetArrayLength(); + } + + if ((this.backing & Backing.Array) != 0) + { + return this.arrayBacking.Count; + } + + return 0; + } + + /// + public JsonArrayEnumerator EnumerateArray() + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Array) != 0) + { + return new(this.arrayBacking); + } + + throw new InvalidOperationException(); + } + + /// + JsonArrayEnumerator IJsonArray.EnumerateArray() + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Array) != 0) + { + return new(this.arrayBacking); + } + + throw new InvalidOperationException(); + } + + /// + JsonArrayEnumerator IJsonArray.EnumerateArray() + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Array) != 0) + { + return new(this.arrayBacking); + } + + throw new InvalidOperationException(); + } + + /// + JsonStringArray IJsonArray.Add(in JsonAny item1) + { + ImmutableList.Builder builder = __CorvusArrayHelpers.GetImmutableListBuilder(this); + builder.Add(item1); + return new(builder.ToImmutable()); + } + + /// + JsonStringArray IJsonArray.Add(params JsonAny[] items) + { + ImmutableList.Builder builder = __CorvusArrayHelpers.GetImmutableListBuilder(this); + foreach (JsonAny item in items) + { + builder.Add(item.AsAny); + } + + return new(builder.ToImmutable()); + } + + /// + JsonStringArray IJsonArray.AddRange(in TArray items) + { + ImmutableList.Builder builder = __CorvusArrayHelpers.GetImmutableListBuilder(this); + foreach (JsonAny item in items.EnumerateArray()) + { + builder.Add(item.AsAny); + } + + return new(builder.ToImmutable()); + } + + /// + JsonStringArray IJsonArray.AddRange(IEnumerable items) + { + ImmutableList.Builder builder = __CorvusArrayHelpers.GetImmutableListBuilder(this); + foreach (TItem item in items) + { + builder.Add(item.AsAny); + } + + return new(builder.ToImmutable()); + } + + /// + JsonStringArray IJsonArray.AddRange(IEnumerable items) + { + ImmutableList.Builder builder = __CorvusArrayHelpers.GetImmutableListBuilder(this); + builder.AddRange(items); + return new(builder.ToImmutable()); + } + + /// + JsonStringArray IJsonArray.Insert(int index, in JsonAny item1) + { + return new(__CorvusArrayHelpers.GetImmutableListWith(this, index, item1)); + } + + /// + JsonStringArray IJsonArray.InsertRange(int index, in TArray items) + { + return new(__CorvusArrayHelpers.GetImmutableListWith(this, index, items.EnumerateArray())); + } + + /// + JsonStringArray IJsonArray.InsertRange(int index, IEnumerable items) + { + return new(__CorvusArrayHelpers.GetImmutableListWith(this, index, items.Select(item => item.AsAny))); + } + + /// + JsonStringArray IJsonArray.InsertRange(int index, IEnumerable items) + { + return new(__CorvusArrayHelpers.GetImmutableListWith(this, index, items)); + } + + /// + JsonStringArray IJsonArray.Replace(in JsonAny oldValue, in JsonAny newValue) + { + return new(__CorvusArrayHelpers.GetImmutableListReplacing(this, oldValue, newValue)); + } + + /// + JsonStringArray IJsonArray.SetItem(int index, in JsonAny value) + { + return new(__CorvusArrayHelpers.GetImmutableListSetting(this, index, value)); + } + + /// + public JsonStringArray Add(in Corvus.Json.JsonString item1) + { + ImmutableList.Builder builder = __CorvusArrayHelpers.GetImmutableListBuilder(this); + builder.Add(item1.AsAny); + return new(builder.ToImmutable()); + } + + /// + public JsonStringArray Add(params Corvus.Json.JsonString[] items) + { + ImmutableList.Builder builder = __CorvusArrayHelpers.GetImmutableListBuilder(this); + foreach (Corvus.Json.JsonString item in items) + { + builder.Add(item.AsAny); + } + + return new(builder.ToImmutable()); + } + + /// + public JsonStringArray AddRange(IEnumerable items) + { + ImmutableList.Builder builder = __CorvusArrayHelpers.GetImmutableListBuilder(this); + foreach (Corvus.Json.JsonString item in items) + { + builder.Add(item.AsAny); + } + + return new(builder.ToImmutable()); + } + + /// + public JsonStringArray Insert(int index, in Corvus.Json.JsonString item1) + { + return new(__CorvusArrayHelpers.GetImmutableListWith(this, index, item1)); + } + + /// + public JsonStringArray InsertRange(int index, IEnumerable items) + { + return new(__CorvusArrayHelpers.GetImmutableListWith(this, index, items.Select(item => item.AsAny))); + } + + /// + public JsonStringArray Replace(in Corvus.Json.JsonString oldValue, in Corvus.Json.JsonString newValue) + { + return new(__CorvusArrayHelpers.GetImmutableListReplacing(this, oldValue, newValue)); + } + + /// + public JsonStringArray SetItem(int index, in Corvus.Json.JsonString value) + { + return new(__CorvusArrayHelpers.GetImmutableListSetting(this, index, value)); + } + + /// + JsonStringArray IJsonArray.Remove(in JsonAny oldValue) + { + return new(__CorvusArrayHelpers.GetImmutableListWithout(this, oldValue)); + } + + /// + JsonStringArray IJsonArray.RemoveAt(int index) + { + return new(__CorvusArrayHelpers.GetImmutableListWithoutRange(this, index, 1)); + } + + /// + JsonStringArray IJsonArray.RemoveRange(int index, int count) + { + return new(__CorvusArrayHelpers.GetImmutableListWithoutRange(this, index, count)); + } + + /// + public JsonStringArray Remove(in Corvus.Json.JsonString oldValue) + { + return new(__CorvusArrayHelpers.GetImmutableListWithout(this, oldValue)); + } + + private static class __CorvusArrayHelpers + { + /// + /// Builds an from the array. + /// + /// The array instance. + /// An immutable list of built from the array. + /// The value is not an array. + public static ImmutableList GetImmutableList(in JsonStringArray arrayInstance) + { + if ((arrayInstance.backing & Backing.Array) != 0) + { + return arrayInstance.arrayBacking; + } + + return GetImmutableListBuilder(arrayInstance).ToImmutable(); + } + + /// + /// Builds an from the array. + /// + /// The array instance. + /// An immutable list builder of , built from the existing array. + /// The value is not an array. + public static ImmutableList.Builder GetImmutableListBuilder(in JsonStringArray arrayInstance) + { + if ((arrayInstance.backing & Backing.JsonElement) != 0) + { + if (arrayInstance.jsonElementBacking.ValueKind == JsonValueKind.Array) + { + ImmutableList.Builder builder = ImmutableList.CreateBuilder(); + foreach (JsonElement item in arrayInstance.jsonElementBacking.EnumerateArray()) + { + builder.Add(new(item)); + } + + return builder; + } + } + + if ((arrayInstance.backing & Backing.Array) != 0) + { + return arrayInstance.arrayBacking.ToBuilder(); + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the array, replacing the item at the specified index with the given item. + /// + /// The array instance. + /// The index at which to add the element. + /// The value to add. + /// An immutable list containing the contents of the list, with the specified item at the index. + /// The value is not an array. + /// Thrown if the range is beyond the bounds of the array. + public static ImmutableList GetImmutableListSetting(in JsonStringArray arrayInstance, int index, in JsonAny value) + { + if ((arrayInstance.backing & Backing.JsonElement) != 0) + { + if (arrayInstance.jsonElementBacking.ValueKind == JsonValueKind.Array) + { + return JsonValueHelpers.GetImmutableListFromJsonElementSetting(arrayInstance.jsonElementBacking, index, value); + } + } + + if ((arrayInstance.backing & Backing.Array) != 0) + { + try + { + return arrayInstance.arrayBacking.SetItem(index, value); + } + catch (ArgumentOutOfRangeException ex) + { + throw new IndexOutOfRangeException(ex.Message, ex); + } + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the array, removing the first item that equals the given value, and replacing it with the specified item. + /// + /// The array instance. + /// The item to remove. + /// The item to insert. + /// An immutable list containing the contents of the list, without the first instance that matches the old item, replacing it with the new item. + /// The value is not an array. + public static ImmutableList GetImmutableListReplacing(in JsonStringArray arrayInstance, in JsonAny oldItem, in JsonAny newItem) + { + if ((arrayInstance.backing & Backing.JsonElement) != 0) + { + if (arrayInstance.jsonElementBacking.ValueKind == JsonValueKind.Array) + { + return JsonValueHelpers.GetImmutableListFromJsonElementReplacing(arrayInstance.jsonElementBacking, oldItem, newItem); + } + } + + if ((arrayInstance.backing & Backing.Array) != 0) + { + return arrayInstance.arrayBacking.Replace(oldItem, newItem); + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the array, removing the first item arrayInstance equals the given value. + /// + /// The array instance. + /// The item to remove. + /// An immutable list containing the contents of the list, without the first instance arrayInstance matches the given item. + /// The value is not an array. + public static ImmutableList GetImmutableListWithout(in JsonStringArray arrayInstance, in JsonAny item) + { + if ((arrayInstance.backing & Backing.JsonElement) != 0) + { + if (arrayInstance.jsonElementBacking.ValueKind == JsonValueKind.Array) + { + return JsonValueHelpers.GetImmutableListFromJsonElementWithout(arrayInstance.jsonElementBacking, item); + } + } + + if ((arrayInstance.backing & Backing.Array) != 0) + { + return arrayInstance.arrayBacking.Remove(item); + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the array, removing the given range. + /// + /// The array instance. + /// The start index of the range to remove. + /// The length of the range to remove. + /// An immutable list containing the contents of the list, without the given range of items. + /// The value is not an array. + /// Thrown if the range is beyond the bounds of the array. + public static ImmutableList GetImmutableListWithoutRange(in JsonStringArray arrayInstance, int index, int count) + { + if ((arrayInstance.backing & Backing.JsonElement) != 0) + { + if (arrayInstance.jsonElementBacking.ValueKind == JsonValueKind.Array) + { + return JsonValueHelpers.GetImmutableListFromJsonElementWithoutRange(arrayInstance.jsonElementBacking, index, count); + } + } + + if ((arrayInstance.backing & Backing.Array) != 0) + { + try + { + return arrayInstance.arrayBacking.RemoveRange(index, count); + } + catch (ArgumentOutOfRangeException ex) + { + throw new IndexOutOfRangeException(ex.Message, ex); + } + } + + throw new InvalidOperationException(); + } + + // + // Builds an from the array, inserting the given item at the index. + // + // The array instance. + // The index at which to add the element. + // The value to add. + // An immutable list containing the contents of the list, without the array. + // The value is not an array. + // Thrown if the range is beyond the bounds of the array. + public static ImmutableList GetImmutableListWith(in JsonStringArray arrayInstance, int index, in JsonAny value) + { + if ((arrayInstance.backing & Backing.JsonElement) != 0) + { + if (arrayInstance.jsonElementBacking.ValueKind == JsonValueKind.Array) + { + return JsonValueHelpers.GetImmutableListFromJsonElementWith(arrayInstance.jsonElementBacking, index, value); + } + } + + if ((arrayInstance.backing & Backing.Array) != 0) + { + try + { + return arrayInstance.arrayBacking.Insert(index, value); + } + catch (ArgumentOutOfRangeException ex) + { + throw new IndexOutOfRangeException(ex.Message, ex); + } + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the array, inserting the items at the + /// given index. + /// + /// The array instance. + /// The index at which to add the element. + /// The values to add. + /// An immutable list containing the contents of the list, without the array. + /// The value is not an array. + /// Thrown if the range is beyond the bounds of the array. + public static ImmutableList GetImmutableListWith(in JsonStringArray arrayInstance, int index, TEnumerable values) + where TEnumerable : IEnumerable + { + if ((arrayInstance.backing & Backing.JsonElement) != 0) + { + if (arrayInstance.jsonElementBacking.ValueKind == JsonValueKind.Array) + { + return JsonValueHelpers.GetImmutableListFromJsonElementWith(arrayInstance.jsonElementBacking, index, values); + } + } + + if ((arrayInstance.backing & Backing.Array) != 0) + { + try + { + return arrayInstance.arrayBacking.InsertRange(index, values); + } + catch (ArgumentOutOfRangeException ex) + { + throw new IndexOutOfRangeException(ex.Message, ex); + } + } + + throw new InvalidOperationException(); + } + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.Validate.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.Validate.cs new file mode 100644 index 000000000..2ddc25075 --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.Validate.cs @@ -0,0 +1,167 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Corvus.Json; + +namespace Sandbox; + +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + /// Generated from JSON Schema. + /// + public readonly partial struct JsonStringArray + { + /// + public ValidationContext Validate(in ValidationContext validationContext, ValidationLevel level = ValidationLevel.Flag) + { + ValidationContext result = validationContext; + if (level > ValidationLevel.Flag && !result.IsUsingResults) + { + result = result.UsingResults(); + } + + if (level > ValidationLevel.Basic) + { + if (!result.IsUsingStack) + { + result = result.UsingStack(); + } + + result = result.PushSchemaLocation("#/properties/someArray"); + } + + JsonValueKind valueKind = this.ValueKind; + + result = CorvusValidation.TypeValidationHandler(valueKind, result, level); + + if (level == ValidationLevel.Flag && !result.IsValid) + { + return result; + } + + result = CorvusValidation.ArrayValidationHandler(this, valueKind, result, level); + + if (level == ValidationLevel.Flag && !result.IsValid) + { + return result; + } + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + + return result; + } + + /// + /// Validation constants for the type. + /// + public static partial class CorvusValidation + { + /// + /// Core type validation. + /// + /// The of the value to validate. + /// The current validation context. + /// The current validation level. + /// The resulting validation context after validation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ValidationContext TypeValidationHandler( + JsonValueKind valueKind, + in ValidationContext validationContext, + ValidationLevel level = ValidationLevel.Flag) + { + return Corvus.Json.ValidateWithoutCoreType.TypeArray(valueKind, validationContext, level, "type"); + } + + /// + /// Array validation. + /// + /// The value to validate. + /// The of the value to validate. + /// The current validation context. + /// The current validation level. + /// The resulting validation context after validation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ValidationContext ArrayValidationHandler( + in JsonStringArray value, + JsonValueKind valueKind, + in ValidationContext validationContext, + ValidationLevel level) + { + ValidationContext result = validationContext; + if (valueKind != JsonValueKind.Array) + { + if (level == ValidationLevel.Verbose) + { + ValidationContext ignoredResult = validationContext; + ignoredResult = ignoredResult.WithResult(isValid: true, "Validation items - ignored because the value is not an array", "items"); + + return ignoredResult; + } + + return validationContext; + } + + int length = 0; + using JsonArrayEnumerator arrayEnumerator = value.EnumerateArray(); + while (arrayEnumerator.MoveNext()) + { + if (level > ValidationLevel.Basic) + { + result = result.PushDocumentArrayIndex(length); + } + if (level > ValidationLevel.Basic) + { + result = result.PushValidationLocationReducedPathModifier(new("#/items")); + } + + var nonTupleItemsResult = arrayEnumerator.Current.Validate(result.CreateChildContext(), level); + if (level == ValidationLevel.Flag && !nonTupleItemsResult.IsValid) + { + return nonTupleItemsResult; + } + + result = result.MergeResults(nonTupleItemsResult.IsValid, level, nonTupleItemsResult); + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + + result = result.WithLocalItemIndex(length); + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + + length++; + } + + return result; + } + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.cs new file mode 100644 index 000000000..fa265903c --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.JsonStringArray.cs @@ -0,0 +1,679 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Buffers; +using System.Collections.Immutable; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Corvus.Json; +using Corvus.Json.Internal; + +namespace Sandbox; + +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + /// Generated from JSON Schema. + /// + [System.Text.Json.Serialization.JsonConverter(typeof(Corvus.Json.Internal.JsonValueConverter))] + public readonly partial struct JsonStringArray + + { + private readonly Backing backing; + private readonly JsonElement jsonElementBacking; + private readonly ImmutableList arrayBacking; + + /// + /// Initializes a new instance of the struct. + /// + public JsonStringArray() + { + this.jsonElementBacking = default; + this.backing = Backing.JsonElement; + this.arrayBacking = ImmutableList.Empty; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public JsonStringArray(in JsonElement value) + { + this.jsonElementBacking = value; + this.backing = Backing.JsonElement; + this.arrayBacking = ImmutableList.Empty; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public JsonStringArray(ImmutableList value) + { + this.backing = Backing.Array; + this.jsonElementBacking = default; + this.arrayBacking = value; + } + + /// + /// Gets the schema location from which this type was generated. + /// + public static string SchemaLocation { get; } = "#/properties/someArray"; + + /// + /// Gets a Null instance. + /// + public static JsonStringArray Null { get; } = new(JsonValueHelpers.NullElement); + + /// + /// Gets an Undefined instance. + /// + public static JsonStringArray Undefined { get; } + + /// + /// Gets the default instance. + /// + public static JsonStringArray DefaultInstance { get; } + + /// + public JsonAny AsAny + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Array) != 0) + { + return new(this.arrayBacking); + } + + if ((this.backing & Backing.Null) != 0) + { + return JsonAny.Null; + } + + return JsonAny.Undefined; + } + } + + /// + public JsonElement AsJsonElement + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking; + } + + if ((this.backing & Backing.Array) != 0) + { + return JsonValueHelpers.ArrayToJsonElement(this.arrayBacking); + } + + if ((this.backing & Backing.Null) != 0) + { + return JsonValueHelpers.NullElement; + } + + return default; + } + } + + /// + JsonString IJsonValue.AsString + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonBoolean IJsonValue.AsBoolean + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonNumber IJsonValue.AsNumber + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonObject IJsonValue.AsObject + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + public JsonArray AsArray + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Array) != 0) + { + return new(this.arrayBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + public bool HasJsonElementBacking + { + get + { + return (this.backing & Backing.JsonElement) != 0; + } + } + + /// + public bool HasDotnetBacking + { + get + { + return (this.backing & Backing.Dotnet) != 0; + } + } + + /// + public JsonValueKind ValueKind + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.ValueKind; + } + + if ((this.backing & Backing.Array) != 0) + { + return JsonValueKind.Array; + } + + return JsonValueKind.Undefined; + } + } + + /// + /// Conversion from JsonAny. + /// + /// The value from which to convert. + public static implicit operator JsonStringArray(JsonAny value) + { + return value.As(); + } + + /// + /// Conversion to JsonAny. + /// + /// The value from which to convert. + public static implicit operator JsonAny(JsonStringArray value) + { + return value.AsAny; + } + + /// + /// Operator ==. + /// + /// The lhs of the operator. + /// The rhs of the operator. + /// + /// True if the values are equal. + /// + public static bool operator ==(in JsonStringArray left, in JsonStringArray right) + { + return left.Equals(right); + } + + /// + /// Operator !=. + /// + /// The lhs of the operator. + /// The rhs of the operator. + /// + /// True if the values are not equal. + /// + public static bool operator !=(in JsonStringArray left, in JsonStringArray right) + { + return !left.Equals(right); + } + + /// + /// Gets an instance of the JSON value from a value. + /// + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the . + /// The returned value will have a of if the + /// value cannot be constructed from the given instance (e.g. because they have an incompatible .NET backing type). + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static JsonStringArray FromJson(in JsonElement value) + { + return new(value); + } + + /// + /// Gets an instance of the JSON value from a value. + /// + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static JsonStringArray FromAny(in JsonAny value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return value.ValueKind switch + { + JsonValueKind.Array => new(value.AsArray.AsImmutableList()), + JsonValueKind.Null => Null, + _ => Undefined, + }; + } + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static JsonStringArray IJsonValue.FromBoolean(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static JsonStringArray IJsonValue.FromString(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static JsonStringArray IJsonValue.FromNumber(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static JsonStringArray IJsonValue.FromObject(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static JsonStringArray FromArray(in TValue value) + where TValue : struct, IJsonArray + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return value.ValueKind switch + { + JsonValueKind.Array => new(value.AsImmutableList()), + JsonValueKind.Null => Null, + _ => Undefined, + }; + } + + /// + /// Parses the JsonStringArray. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static JsonStringArray Parse(string source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the JsonStringArray. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static JsonStringArray Parse(Stream source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the JsonStringArray. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static JsonStringArray Parse(ReadOnlyMemory source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the JsonStringArray. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static JsonStringArray Parse(ReadOnlyMemory source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the JsonStringArray. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static JsonStringArray Parse(ReadOnlySequence source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the JsonStringArray. + /// + /// The source of the JSON string to parse. + public static JsonStringArray ParseValue(string source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source.AsSpan()); +#endif + } + + /// + /// Parses the JsonStringArray. + /// + /// The source of the JSON string to parse. + public static JsonStringArray ParseValue(ReadOnlySpan source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source); +#endif + } + + /// + /// Parses the JsonStringArray. + /// + /// The source of the JSON string to parse. + public static JsonStringArray ParseValue(ReadOnlySpan source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source); +#endif + } + + /// + /// Parses the JsonStringArray. + /// + /// The source of the JSON string to parse. + public static JsonStringArray ParseValue(ref Utf8JsonReader source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(ref source); +#else + return JsonValueHelpers.ParseValue(ref source); +#endif + } + + /// + /// Gets the value as an instance of the target value. + /// + /// The type of the target. + /// An instance of the target type. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TTarget As() + where TTarget : struct, IJsonValue + { +#if NET8_0_OR_GREATER + if ((this.backing & Backing.JsonElement) != 0) + { + return TTarget.FromJson(this.jsonElementBacking); + } + + if ((this.backing & Backing.Array) != 0) + { + return TTarget.FromArray(this); + } + + if ((this.backing & Backing.Null) != 0) + { + return TTarget.Null; + } + + return TTarget.Undefined; +#else + return this.As(); +#endif + } + + /// + public override bool Equals(object? obj) + { + return + (obj is IJsonValue jv && this.Equals(jv.As())) || + (obj is null && this.IsNull()); + } + + /// + public bool Equals(in T other) + where T : struct, IJsonValue + { + return this.Equals(other.As()); + } + + /// + /// Equality comparison. + /// + /// The other item with which to compare. + /// if the values were equal. + public bool Equals(in JsonStringArray other) + { + JsonValueKind thisKind = this.ValueKind; + JsonValueKind otherKind = other.ValueKind; + if (thisKind != otherKind) + { + return false; + } + + if (thisKind == JsonValueKind.Null || thisKind == JsonValueKind.Undefined) + { + return true; + } + + if (thisKind == JsonValueKind.Array) + { + JsonArrayEnumerator lhs = this.EnumerateArray(); + JsonArrayEnumerator rhs = other.EnumerateArray(); + while (lhs.MoveNext()) + { + if (!rhs.MoveNext()) + { + return false; + } + + if (!lhs.Current.Equals(rhs.Current)) + { + return false; + } + } + + return !rhs.MoveNext(); + } + + return false; + } + + /// + public void WriteTo(Utf8JsonWriter writer) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Undefined) + { + this.jsonElementBacking.WriteTo(writer); + } + + return; + } + + if ((this.backing & Backing.Array) != 0) + { + JsonValueHelpers.WriteItems(this.arrayBacking, writer); + + return; + } + + if ((this.backing & Backing.Null) != 0) + { + writer.WriteNullValue(); + + return; + } + } + + /// + public override int GetHashCode() + { + return this.ValueKind switch + { + JsonValueKind.Array => JsonValueHelpers.GetArrayHashCode(this), + JsonValueKind.Object => JsonValueHelpers.GetObjectHashCode(((IJsonValue)this).AsObject), + JsonValueKind.Number => JsonValueHelpers.GetHashCodeForNumber(((IJsonValue)this).AsNumber), + JsonValueKind.String => JsonValueHelpers.GetHashCodeForString(((IJsonValue)this).AsString), + JsonValueKind.True => true.GetHashCode(), + JsonValueKind.False => false.GetHashCode(), + JsonValueKind.Null => JsonValueHelpers.NullHashCode, + _ => JsonValueHelpers.UndefinedHashCode, + }; + } + + /// + public override string ToString() + { + return this.Serialize(); + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.Object.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.Object.cs new file mode 100644 index 000000000..1aceb571b --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.Object.cs @@ -0,0 +1,1053 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Collections.Immutable; +using System.Text.Json; +using Corvus.Json; +using Corvus.Json.Internal; + +namespace Sandbox; +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel + : IJsonObject +{ + /// + /// Conversion from . + /// + /// The value from which to convert. + public static implicit operator TestModel(ImmutableList value) + { + return new(value); + } + + /// + /// Conversion to . + /// + /// The value from which to convert. + public static implicit operator ImmutableList(TestModel value) + { + return + __CorvusObjectHelpers.GetPropertyBacking(value); + } + + /// + /// Conversion from JsonObject. + /// + /// The value from which to convert. + public static implicit operator TestModel(JsonObject value) + { + if (value.HasDotnetBacking && value.ValueKind == JsonValueKind.Object) + { + return new( + __CorvusObjectHelpers.GetPropertyBacking(value)); + } + + return new(value.AsJsonElement); + } + + /// + /// Conversion to JsonObject. + /// + /// The value from which to convert. + public static implicit operator JsonObject(TestModel value) + { + return + value.AsObject; + } + + /// + public Corvus.Json.JsonAny this[in JsonPropertyName name] + { + get + { + if (this.TryGetProperty(name, out Corvus.Json.JsonAny result)) + { + return result; + } + + throw new InvalidOperationException(); + } + } + + /// + /// Gets the number of properties in the object. + /// + public int Count + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.GetPropertyCount(); + } + + if ((this.backing & Backing.Object) != 0) + { + return this.objectBacking.Count; + } + + throw new InvalidOperationException(); + } + } + + /// + /// Gets the (optional) someArray property. + /// + /// + /// + /// If this JSON property is then the value returned will be . + /// + /// + public Sandbox.TestModel.JsonStringArray? SomeArray + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + return default; + } + + if (this.jsonElementBacking.TryGetProperty(JsonPropertyNames.SomeArrayUtf8, out JsonElement result)) + { + if (result.ValueKind == JsonValueKind.Null || result.ValueKind == JsonValueKind.Undefined) + { + return default; + } + + return new(result); + } + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(JsonPropertyNames.SomeArray, out JsonAny result)) + { + if (result.IsNullOrUndefined()) + { + return default; + } + + return result.As(); + } + } + + return default; + } + } + + /// + /// Gets the (optional) someBool property. + /// + /// + /// + /// If this JSON property is then the value returned will be . + /// + /// + public Corvus.Json.JsonBoolean? SomeBool + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + return default; + } + + if (this.jsonElementBacking.TryGetProperty(JsonPropertyNames.SomeBoolUtf8, out JsonElement result)) + { + if (result.ValueKind == JsonValueKind.Null || result.ValueKind == JsonValueKind.Undefined) + { + return default; + } + + return new(result); + } + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(JsonPropertyNames.SomeBool, out JsonAny result)) + { + if (result.IsNullOrUndefined()) + { + return default; + } + + return result.As(); + } + } + + return default; + } + } + + /// + /// Gets the (optional) someNumber property. + /// + /// + /// + /// If this JSON property is then the value returned will be . + /// + /// + public Sandbox.TestModel.SomeNumberEntity? SomeNumber + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + return default; + } + + if (this.jsonElementBacking.TryGetProperty(JsonPropertyNames.SomeNumberUtf8, out JsonElement result)) + { + if (result.ValueKind == JsonValueKind.Null || result.ValueKind == JsonValueKind.Undefined) + { + return default; + } + + return new(result); + } + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(JsonPropertyNames.SomeNumber, out JsonAny result)) + { + if (result.IsNullOrUndefined()) + { + return default; + } + + return result.As(); + } + } + + return default; + } + } + + /// + /// Gets the (optional) someString property. + /// + /// + /// + /// If this JSON property is then the value returned will be . + /// + /// + public Sandbox.TestModel.SomeStringEntity? SomeString + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + return default; + } + + if (this.jsonElementBacking.TryGetProperty(JsonPropertyNames.SomeStringUtf8, out JsonElement result)) + { + if (result.ValueKind == JsonValueKind.Null || result.ValueKind == JsonValueKind.Undefined) + { + return default; + } + + return new(result); + } + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(JsonPropertyNames.SomeString, out JsonAny result)) + { + if (result.IsNullOrUndefined()) + { + return default; + } + + return result.As(); + } + } + + return default; + } + } + + /// + public static TestModel FromProperties(IDictionary source) + { + return new(source.Select(kvp => new JsonObjectProperty(kvp.Key, kvp.Value)).ToImmutableList()); + } + + /// + public static TestModel FromProperties(params (JsonPropertyName Name, JsonAny Value)[] source) + { + return new(source.Select(s => new JsonObjectProperty(s.Name, s.Value.AsAny)).ToImmutableList()); + } + + /// + /// Creates an instance of the type from the given immutable list of properties. + /// + /// The list of properties. + /// An instance of the type initialized from the list of properties. + public static TestModel FromProperties(ImmutableList source) + { + return new(source); + } + + /// + /// Creates an instance of a . + /// + public static TestModel Create( + in Sandbox.TestModel.JsonStringArray? someArray = null, + in Corvus.Json.JsonBoolean? someBool = null, + in Sandbox.TestModel.SomeNumberEntity? someNumber = null, + in Sandbox.TestModel.SomeStringEntity? someString = null) + { + var builder = ImmutableList.CreateBuilder(); + + if (someArray is not null) + { + builder.Add(JsonPropertyNames.SomeArray, someArray.Value.AsAny); + } + + if (someBool is not null) + { + builder.Add(JsonPropertyNames.SomeBool, someBool.Value.AsAny); + } + + if (someNumber is not null) + { + builder.Add(JsonPropertyNames.SomeNumber, someNumber.Value.AsAny); + } + + if (someString is not null) + { + builder.Add(JsonPropertyNames.SomeString, someString.Value.AsAny); + } + + return new(builder.ToImmutable()); + } + + /// + public ImmutableList AsPropertyBacking() + { + return __CorvusObjectHelpers.GetPropertyBacking(this); + } + /// + public ImmutableList.Builder AsPropertyBackingBuilder() + { + return __CorvusObjectHelpers.GetPropertyBacking(this).ToBuilder(); + } + + /// + public JsonObjectEnumerator EnumerateObject() + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Object) != 0) + { + return new(this.objectBacking); + } + + throw new InvalidOperationException(); + } + + /// + public bool HasProperties() + { + if ((this.backing & Backing.Object) != 0) + { + return this.objectBacking.Count > 0; + } + + if ((this.backing & Backing.JsonElement) != 0) + { + using JsonElement.ObjectEnumerator enumerator = this.jsonElementBacking.EnumerateObject(); + return enumerator.MoveNext(); + } + + throw new InvalidOperationException(); + } + + /// + public bool HasProperty(in JsonPropertyName name) + { + if ((this.backing & Backing.Object) != 0) + { + return this.objectBacking.ContainsKey(name); + } + + if ((this.backing & Backing.JsonElement) != 0) + { + return name.TryGetProperty(this.jsonElementBacking, out JsonElement _); + } + + throw new InvalidOperationException(); + } + + /// + public bool HasProperty(string name) + { + if ((this.backing & Backing.Object) != 0) + { + return this.objectBacking.ContainsKey(name); + } + + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.TryGetProperty(name, out _); + } + + throw new InvalidOperationException(); + } + + /// + public bool HasProperty(ReadOnlySpan name) + { + if ((this.backing & Backing.Object) != 0) + { + return this.objectBacking.ContainsKey(name); + } + + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.TryGetProperty(name, out _); + } + + throw new InvalidOperationException(); + } + + /// + public bool HasProperty(ReadOnlySpan name) + { + if ((this.backing & Backing.Object) != 0) + { + return this.objectBacking.ContainsKey(name); + } + + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.TryGetProperty(name, out _); + } + + throw new InvalidOperationException(); + } + + /// + /// Sets the (optional) someArray property. + /// + /// The new property value + /// The instance with the property set. + public TestModel WithSomeArray(in Sandbox.TestModel.JsonStringArray? value) + { + return value.HasValue ? this.SetProperty(JsonPropertyNames.SomeArray, value.Value) : this.RemoveProperty(JsonPropertyNames.SomeArray); + } + + /// + /// Sets the (optional) someBool property. + /// + /// The new property value + /// The instance with the property set. + public TestModel WithSomeBool(in Corvus.Json.JsonBoolean? value) + { + return value.HasValue ? this.SetProperty(JsonPropertyNames.SomeBool, value.Value) : this.RemoveProperty(JsonPropertyNames.SomeBool); + } + + /// + /// Sets the (optional) someNumber property. + /// + /// The new property value + /// The instance with the property set. + public TestModel WithSomeNumber(in Sandbox.TestModel.SomeNumberEntity? value) + { + return value.HasValue ? this.SetProperty(JsonPropertyNames.SomeNumber, value.Value) : this.RemoveProperty(JsonPropertyNames.SomeNumber); + } + + /// + /// Sets the (optional) someString property. + /// + /// The new property value + /// The instance with the property set. + public TestModel WithSomeString(in Sandbox.TestModel.SomeStringEntity? value) + { + return value.HasValue ? this.SetProperty(JsonPropertyNames.SomeString, value.Value) : this.RemoveProperty(JsonPropertyNames.SomeString); + } + + /// + /// Get a property. + /// + /// The name of the property. + /// The value of the property. + /// True if the property was present. + /// The value is not an object. + public bool TryGetProperty(in JsonPropertyName name, out JsonAny value) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + value = default; + return false; + } + + if (name.TryGetProperty(this.jsonElementBacking, out JsonElement element)) + { + value = new(element); + return true; + } + + value = default; + return false; + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(name, out JsonAny result)) + { + value = result; + return true; + } + + value = default; + return false; + } + + throw new InvalidOperationException(); + } + + /// + /// Get a property. + /// + /// The name of the property. + /// The value of the property. + /// True if the property was present. + /// The value is not an object. + public bool TryGetProperty(string name, out JsonAny value) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + value = default; + return false; + } + + if (this.jsonElementBacking.TryGetProperty(name, out JsonElement element)) + { + value = new(element); + return true; + } + + value = default; + return false; + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(name, out JsonAny result)) + { + value = result; + return true; + } + + value = default; + return false; + } + + throw new InvalidOperationException(); + } + + /// + /// Get a property. + /// + /// The name of the property. + /// The value of the property. + /// True if the property was present. + /// The value is not an object. + public bool TryGetProperty(ReadOnlySpan name, out JsonAny value) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + value = default; + return false; + } + + if (this.jsonElementBacking.TryGetProperty(name, out JsonElement element)) + { + value = new(element); + return true; + } + + value = default; + return false; + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(name, out JsonAny result)) + { + value = result; + return true; + } + + value = default; + return false; + } + + throw new InvalidOperationException(); + } + + /// + /// Get a property. + /// + /// The name of the property. + /// The value of the property. + /// True if the property was present. + /// The value is not an object. + public bool TryGetProperty(ReadOnlySpan name, out JsonAny value) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + value = default; + return false; + } + + if (this.jsonElementBacking.TryGetProperty(name, out JsonElement element)) + { + value = new(element); + return true; + } + + value = default; + return false; + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(name, out JsonAny result)) + { + value = result; + return true; + } + + value = default; + return false; + } + + throw new InvalidOperationException(); + } + + /// + public bool TryGetProperty(in JsonPropertyName name, out TValue value) + where TValue : struct, IJsonValue + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + value = default; + return false; + } + + if (name.TryGetProperty(this.jsonElementBacking, out JsonElement element)) + { +#if NET8_0_OR_GREATER + value = TValue.FromJson(element); +#else + value = JsonValueNetStandard20Extensions.FromJsonElement(element); +#endif + + return true; + } + + value = default; + return false; + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(name, out JsonAny result)) + { +#if NET8_0_OR_GREATER + value = TValue.FromAny(result); +#else + value = result.As(); +#endif + return true; + } + + value = default; + return false; + } + + throw new InvalidOperationException(); + } + + /// + public bool TryGetProperty(string name, out TValue value) + where TValue : struct, IJsonValue + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + value = default; + return false; + } + + if (this.jsonElementBacking.TryGetProperty(name, out JsonElement element)) + { +#if NET8_0_OR_GREATER + value = TValue.FromJson(element); +#else + value = JsonValueNetStandard20Extensions.FromJsonElement(element); +#endif + + return true; + } + + value = default; + return false; + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(name, out JsonAny result)) + { +#if NET8_0_OR_GREATER + value = TValue.FromAny(result); +#else + value = result.As(); +#endif + return true; + } + + value = default; + return false; + } + + throw new InvalidOperationException(); + } + + /// + public bool TryGetProperty(ReadOnlySpan name, out TValue value) + where TValue : struct, IJsonValue + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + value = default; + return false; + } + + if (this.jsonElementBacking.TryGetProperty(name, out JsonElement element)) + { +#if NET8_0_OR_GREATER + value = TValue.FromJson(element); +#else + value = JsonValueNetStandard20Extensions.FromJsonElement(element); +#endif + + return true; + } + + value = default; + return false; + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(name, out JsonAny result)) + { +#if NET8_0_OR_GREATER + value = TValue.FromAny(result); +#else + value = result.As(); +#endif + return true; + } + + value = default; + return false; + } + + throw new InvalidOperationException(); + } + + /// + public bool TryGetProperty(ReadOnlySpan name, out TValue value) + where TValue : struct, IJsonValue + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Object) + { + value = default; + return false; + } + + if (this.jsonElementBacking.TryGetProperty(name, out JsonElement element)) + { +#if NET8_0_OR_GREATER + value = TValue.FromJson(element); +#else + value = JsonValueNetStandard20Extensions.FromJsonElement(element); +#endif + + return true; + } + + value = default; + return false; + } + + if ((this.backing & Backing.Object) != 0) + { + if (this.objectBacking.TryGetValue(name, out JsonAny result)) + { +#if NET8_0_OR_GREATER + value = TValue.FromAny(result); +#else + value = result.As(); +#endif + return true; + } + + value = default; + return false; + } + + throw new InvalidOperationException(); + } + + /// + public TestModel SetProperty(in JsonPropertyName name, TValue value) + where TValue : struct, IJsonValue + { + return new(__CorvusObjectHelpers.GetPropertyBackingWith(this, name, value.AsAny)); + } + + /// + public TestModel RemoveProperty(in JsonPropertyName name) + { + return new(__CorvusObjectHelpers.GetPropertyBackingWithout(this, name)); + } + + /// + public TestModel RemoveProperty(string name) + { + return new(__CorvusObjectHelpers.GetPropertyBackingWithout(this, name)); + } + + /// + public TestModel RemoveProperty(ReadOnlySpan name) + { + return new(__CorvusObjectHelpers.GetPropertyBackingWithout(this, name)); + } + + /// + public TestModel RemoveProperty(ReadOnlySpan name) + { + return new(__CorvusObjectHelpers.GetPropertyBackingWithout(this, name)); + } + + /// + /// Provides UTF8 and string versions of the JSON property names on the object. + /// + public static class JsonPropertyNames + { + /// + /// Gets the JSON property name for . + /// + public const string SomeArray = "someArray"; + + /// + /// Gets the JSON property name for . + /// + public const string SomeBool = "someBool"; + + /// + /// Gets the JSON property name for . + /// + public const string SomeNumber = "someNumber"; + + /// + /// Gets the JSON property name for . + /// + public const string SomeString = "someString"; + + /// + /// Gets the JSON property name for . + /// + public static ReadOnlySpan SomeArrayUtf8 => "someArray"u8; + + /// + /// Gets the JSON property name for . + /// + public static ReadOnlySpan SomeBoolUtf8 => "someBool"u8; + + /// + /// Gets the JSON property name for . + /// + public static ReadOnlySpan SomeNumberUtf8 => "someNumber"u8; + + /// + /// Gets the JSON property name for . + /// + public static ReadOnlySpan SomeStringUtf8 => "someString"u8; + } + + private static class __CorvusObjectHelpers + { + /// + /// Builds an from the object. + /// + /// An immutable list of built from the object. + /// The value is not an object. + public static ImmutableList GetPropertyBacking(in TestModel that) + { + if ((that.backing & Backing.Object) != 0) + { + return that.objectBacking; + } + + if ((that.backing & Backing.JsonElement) != 0) + { + return PropertyBackingBuilders.GetPropertyBackingBuilder(that.jsonElementBacking).ToImmutable(); + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the object, without a specific property. + /// + /// An immutable list of , built from the existing object, without the given property. + /// The value is not an object. + public static ImmutableList GetPropertyBackingWithout(in TestModel that, in JsonPropertyName name) + { + if ((that.backing & Backing.Object) != 0) + { + return that.objectBacking.Remove(name); + } + + if ((that.backing & Backing.JsonElement) != 0) + { + return PropertyBackingBuilders.GetPropertyBackingBuilderWithout(that.jsonElementBacking, name).ToImmutable(); + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the object, without a specific property. + /// + /// An immutable list of , built from the existing object, without the given property. + /// The value is not an object. + public static ImmutableList GetPropertyBackingWithout(in TestModel that, ReadOnlySpan name) + { + if ((that.backing & Backing.Object) != 0) + { + return that.objectBacking.Remove(name); + } + + if ((that.backing & Backing.JsonElement) != 0) + { + return PropertyBackingBuilders.GetPropertyBackingBuilderWithout(that.jsonElementBacking, name).ToImmutable(); + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the object, without a specific property. + /// + /// An immutable list of , built from the existing object, without the given property. + /// The value is not an object. + public static ImmutableList GetPropertyBackingWithout(in TestModel that, ReadOnlySpan name) + { + if ((that.backing & Backing.Object) != 0) + { + return that.objectBacking.Remove(name); + } + + if ((that.backing & Backing.JsonElement) != 0) + { + return PropertyBackingBuilders.GetPropertyBackingBuilderWithout(that.jsonElementBacking, name).ToImmutable(); + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the object, without a specific property. + /// + /// An immutable list of , built from the existing object, without the given property. + /// The value is not an object. + public static ImmutableList GetPropertyBackingWithout(in TestModel that, string name) + { + if ((that.backing & Backing.Object) != 0) + { + return that.objectBacking.Remove(name); + } + + if ((that.backing & Backing.JsonElement) != 0) + { + return PropertyBackingBuilders.GetPropertyBackingBuilderWithout(that.jsonElementBacking, name).ToImmutable(); + } + + throw new InvalidOperationException(); + } + + /// + /// Builds an from the object, without a specific property. + /// + /// An immutable list of , built from the existing object, with the given property. + /// The value is not an object. + public static ImmutableList GetPropertyBackingWith(in TestModel that, in JsonPropertyName name, in JsonAny value) + { + if ((that.backing & Backing.Object) != 0) + { + return that.objectBacking.SetItem(name, value); + } + + if ((that.backing & Backing.JsonElement) != 0) + { + return PropertyBackingBuilders.GetPropertyBackingBuilderReplacing(that.jsonElementBacking, name, value).ToImmutable(); + } + + throw new InvalidOperationException(); + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.Number.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.Number.cs new file mode 100644 index 000000000..e7a07a815 --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.Number.cs @@ -0,0 +1,739 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; + +#if NET8_0_OR_GREATER +using System.Numerics; +#endif +using System.Text.Json; +using Corvus.Json; +using Corvus.Json.Internal; + +namespace Sandbox; + +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + /// Generated from JSON Schema. + /// + public readonly partial struct SomeNumberEntity +#if NET8_0_OR_GREATER + : IJsonNumber, + IAdditionOperators, + ISubtractionOperators, + IMultiplyOperators, + IDivisionOperators, + IIncrementOperators, + IDecrementOperators +#else + : IJsonNumber +#endif + { + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public SomeNumberEntity(double value) + : this(new BinaryJsonNumber(value)) + { + } + + /// + /// Conversion from JsonNumber. + /// + /// The value from which to convert. + public static implicit operator SomeNumberEntity(JsonNumber value) + { + if (value.HasDotnetBacking && value.ValueKind == JsonValueKind.Number) + { + return new( + value.AsBinaryJsonNumber); + } + + return new(value.AsJsonElement); + } + + /// + /// Conversion to JsonNumber. + /// + /// The value from which to convert. + public static implicit operator JsonNumber(SomeNumberEntity value) + { + return + value.AsNumber; + } + + /// + /// Conversion to byte. + /// + /// The value from which to convert. + /// An instance of the byte. + public static explicit operator byte(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetByte(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from byte. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(byte value) + { + return new(new BinaryJsonNumber(value)); + } + + /// + /// Conversion to decimal. + /// + /// The value from which to convert. + /// An instance of the decimal. + public static explicit operator decimal(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetDecimal(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from decimal. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(decimal value) + { + return new(new BinaryJsonNumber(value)); + } + + /// + /// Conversion to double. + /// + /// The value from which to convert. + /// An instance of the double. + public static implicit operator double(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetDouble(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from double. + /// + /// The value from which to convert. + /// An instance of the . + public static implicit operator SomeNumberEntity(double value) + { + return new(new BinaryJsonNumber(value)); + } + + /// + /// Conversion to short. + /// + /// The value from which to convert. + /// An instance of the short. + public static explicit operator short(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetInt16(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from short. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(short value) + { + return new(new BinaryJsonNumber(value)); + } + + /// + /// Conversion to int. + /// + /// The value from which to convert. + /// An instance of the int. + public static explicit operator int(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetInt32(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from int. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(int value) + { + return new(new BinaryJsonNumber(value)); + } + + /// + /// Conversion to long. + /// + /// The value from which to convert. + /// An instance of the long. + public static explicit operator long(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetInt64(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from long. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(long value) + { + return new(new BinaryJsonNumber(value)); + } + +#if NET8_0_OR_GREATER + /// + /// Conversion to Int128. + /// + /// The value from which to convert. + /// An instance of the Int128. + public static explicit operator Int128(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetInt128(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from Int128. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(Int128 value) + { + return new(new BinaryJsonNumber(value)); + } +#endif + + /// + /// Conversion to sbyte. + /// + /// The value from which to convert. + /// An instance of the sbyte. + public static explicit operator sbyte(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetSByte(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from sbyte. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(sbyte value) + { + return new(new BinaryJsonNumber(value)); + } + +#if NET8_0_OR_GREATER + /// + /// Conversion to Half. + /// + /// The value from which to convert. + /// An instance of the Half. + public static explicit operator Half(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetHalf(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from Half. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(Half value) + { + return new(new BinaryJsonNumber(value)); + } +#endif + + /// + /// Conversion to float. + /// + /// The value from which to convert. + /// An instance of the float. + public static explicit operator float(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetSingle(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from float. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(float value) + { + return new(new BinaryJsonNumber(value)); + } + + /// + /// Conversion to ushort. + /// + /// The value from which to convert. + /// An instance of the ushort. + public static explicit operator ushort(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetUInt16(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from ushort. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(ushort value) + { + return new(new BinaryJsonNumber(value)); + } + + /// + /// Conversion to uint. + /// + /// The value from which to convert. + /// An instance of the uint. + public static explicit operator uint(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetUInt32(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from uint. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(uint value) + { + return new(new BinaryJsonNumber(value)); + } + + /// + /// Conversion to ulong. + /// + /// The value from which to convert. + /// An instance of the ulong. + public static explicit operator ulong(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetUInt64(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from ulong. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(ulong value) + { + return new(new BinaryJsonNumber(value)); + } + +#if NET8_0_OR_GREATER + /// + /// Conversion to UInt128. + /// + /// The value from which to convert. + /// An instance of the UInt128. + public static explicit operator UInt128(SomeNumberEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + return value.jsonElementBacking.SafeGetUInt128(); + } + + if ((value.backing & Backing.Number) != 0) + { + return value.numberBacking.CreateChecked(); + } + + throw new InvalidOperationException(); + } + + /// + /// Conversion from UInt128. + /// + /// The value from which to convert. + /// An instance of the . + public static explicit operator SomeNumberEntity(UInt128 value) + { + return new(new BinaryJsonNumber(value)); + } +#endif + + /// + /// Less than operator. + /// + /// The LHS of the comparison. + /// The RHS of the comparison. + /// + /// if the left is less than the right, otherwise . + /// + public static bool operator <(SomeNumberEntity left, SomeNumberEntity right) + { + return left.IsNotNullOrUndefined() && right.IsNotNullOrUndefined() && Compare(left, right) < 0; + } + + /// + /// Less than or equals operator. + /// + /// The LHS of the comparison. + /// The RHS of the comparison. + /// + /// if the left is less than or equal to the right, otherwise . + /// + public static bool operator <=(SomeNumberEntity left, SomeNumberEntity right) + { + return left.IsNotNullOrUndefined() && right.IsNotNullOrUndefined() && Compare(left, right) <= 0; + } + + /// + /// Greater than operator. + /// + /// The LHS of the comparison. + /// The RHS of the comparison. + /// + /// if the left is greater than the right, otherwise . + /// + public static bool operator >(SomeNumberEntity left, SomeNumberEntity right) + { + return left.IsNotNullOrUndefined() && right.IsNotNullOrUndefined() && Compare(left, right) > 0; + } + + /// + /// Greater than or equals operator. + /// + /// The LHS of the comparison. + /// The RHS of the comparison. + /// + /// if the left is greater than or equal to the right, otherwise . + /// + public static bool operator >=(SomeNumberEntity left, SomeNumberEntity right) + { + return left.IsNotNullOrUndefined() && right.IsNotNullOrUndefined() && Compare(left, right) >= 0; + } + + /// + /// Adds two numbers to produce their sum. + /// + /// The left hand side of the binary operator. + /// The right hand side of the binary operator. + /// The result of the operation. + public static SomeNumberEntity operator +(SomeNumberEntity left, SomeNumberEntity right) + { + return new(left.AsBinaryJsonNumber + right.AsBinaryJsonNumber); + } + + /// + /// Subtracts two numbers to produce their difference. + /// + /// The left hand side of the binary operator. + /// The right hand side of the binary operator. + /// The result of the operation. + public static SomeNumberEntity operator -(SomeNumberEntity left, SomeNumberEntity right) + { + return new(left.AsBinaryJsonNumber - right.AsBinaryJsonNumber); + } + + /// + /// Multiplies two numbers. + /// + /// The left hand side of the binary operator. + /// The right hand side of the binary operator. + /// The result of the operation. + public static SomeNumberEntity operator *(SomeNumberEntity left, SomeNumberEntity right) + { + return new(left.AsBinaryJsonNumber * right.AsBinaryJsonNumber); + } + + /// + /// Divides two numbers. + /// + /// The left hand side of the binary operator. + /// The right hand side of the binary operator. + /// The result of the operation. + public static SomeNumberEntity operator /(SomeNumberEntity left, SomeNumberEntity right) + { + return new(left.AsBinaryJsonNumber / right.AsBinaryJsonNumber); + } + + /// + /// Increments the number. + /// + /// The value on which to operate. + /// The result of the operation. + public static SomeNumberEntity operator ++(SomeNumberEntity value) + { + BinaryJsonNumber num = value.AsBinaryJsonNumber; return new(num++); + } + + /// + /// Decrements the number. + /// + /// The value on which to operate. + /// The result of the operation. + public static SomeNumberEntity operator --(SomeNumberEntity value) + { + BinaryJsonNumber num = value.AsBinaryJsonNumber; return new(num--); + } + + /// + /// Compare two numbers. + /// + /// The left hand side of the comparison. + /// The right hand side of the comparison. + /// + /// 0 if the numbers are equal, -1 if is less than , + /// and 1 if is greater than . + /// + public static int Compare(in SomeNumberEntity lhs, in SomeNumberEntity rhs) + { + if (lhs.ValueKind != rhs.ValueKind) + { + // We can't be equal if we are not the same underlying type + return lhs.IsNullOrUndefined() ? 1 : -1; + } + + if (lhs.IsNull()) + { + // Nulls are always equal + return 0; + } + + if (lhs.backing == Backing.Number && rhs.backing == Backing.Number) + { + return BinaryJsonNumber.Compare(lhs.numberBacking, rhs.numberBacking); + } + + if (lhs.backing == Backing.Number && rhs.backing == Backing.JsonElement) + { + return BinaryJsonNumber.Compare(lhs.numberBacking, rhs.jsonElementBacking); + } + + if (lhs.backing == Backing.JsonElement && rhs.backing == Backing.Number) + { + return BinaryJsonNumber.Compare(lhs.jsonElementBacking, rhs.numberBacking); + } + + if (lhs.backing == Backing.JsonElement && rhs.backing == Backing.JsonElement && rhs.jsonElementBacking.ValueKind == JsonValueKind.Number) + { + return JsonValueHelpers.NumericCompare(lhs.jsonElementBacking, rhs.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + + /// + /// Gets the value as a . + /// + public BinaryJsonNumber AsBinaryJsonNumber + { + get + { + if ((this.backing & Backing.Number) != 0) + { + return this.numberBacking; + } + + if ((this.backing & Backing.JsonElement) != 0) + { + return BinaryJsonNumber.FromJson(this.jsonElementBacking, BinaryJsonNumber.Kind.Double); + } + + throw new InvalidOperationException(); + } + } + + /// + /// Gets the value as a double. + /// + public double AsDouble() => (double)this; + + /// + /// Equality comparison. + /// + /// The double with which to compare. + /// if the values were equal. + public bool Equals(double other) + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.ValueKind == JsonValueKind.Number && BinaryJsonNumber.Equals(this.jsonElementBacking, new BinaryJsonNumber(other)); + } + + if ((this.backing & Backing.Number) != 0) + { + return BinaryJsonNumber.Equals(new BinaryJsonNumber(other), this.numberBacking); + } + + return false; + } + + /// + /// Equality comparison. + /// + /// The with which to compare. + /// if the values were equal. + public bool Equals(in BinaryJsonNumber other) + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.ValueKind == JsonValueKind.Number && other.Equals(this.jsonElementBacking); + } + + if ((this.backing & Backing.Number) != 0) + { + return BinaryJsonNumber.Equals(other, this.numberBacking); + } + + return false; + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.Validate.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.Validate.cs new file mode 100644 index 000000000..78b037b95 --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.Validate.cs @@ -0,0 +1,193 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Corvus.Json; + +namespace Sandbox; + +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + /// Generated from JSON Schema. + /// + public readonly partial struct SomeNumberEntity + { + /// + public ValidationContext Validate(in ValidationContext validationContext, ValidationLevel level = ValidationLevel.Flag) + { + ValidationContext result = validationContext; + if (level > ValidationLevel.Flag && !result.IsUsingResults) + { + result = result.UsingResults(); + } + + if (level > ValidationLevel.Basic) + { + if (!result.IsUsingStack) + { + result = result.UsingStack(); + } + + result = result.PushSchemaLocation("#/properties/someNumber"); + } + + JsonValueKind valueKind = this.ValueKind; + + result = CorvusValidation.TypeValidationHandler(valueKind, result, level); + + if (level == ValidationLevel.Flag && !result.IsValid) + { + return result; + } + + result = CorvusValidation.NumberValidationHandler(this, valueKind, result, level); + + if (level == ValidationLevel.Flag && !result.IsValid) + { + return result; + } + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + + return result; + } + + /// + /// Validation constants for the type. + /// + public static partial class CorvusValidation + { + /// + /// A constant for the maximum keyword. + /// + public static readonly BinaryJsonNumber Maximum = new(100); + + /// + /// A constant for the minimum keyword. + /// + public static readonly BinaryJsonNumber Minimum = new(0); + + /// + /// Core type validation. + /// + /// The of the value to validate. + /// The current validation context. + /// The current validation level. + /// The resulting validation context after validation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ValidationContext TypeValidationHandler( + JsonValueKind valueKind, + in ValidationContext validationContext, + ValidationLevel level = ValidationLevel.Flag) + { + return Corvus.Json.ValidateWithoutCoreType.TypeNumber(valueKind, validationContext, level, "type"); + } + + /// + /// Numeric validation. + /// + /// The value to validate. + /// The of the value to validate. + /// The current validation context. + /// The current validation level. + /// The resulting validation context after validation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ValidationContext NumberValidationHandler( + in SomeNumberEntity value, + JsonValueKind valueKind, + in ValidationContext validationContext, + ValidationLevel level = ValidationLevel.Flag) + { + if (valueKind != JsonValueKind.Number) + { + if (level == ValidationLevel.Verbose) + { + ValidationContext ignoredResult = validationContext; + ignoredResult = ignoredResult.WithResult(isValid: true, "Validation maximum - ignored because the value is not a number", "maximum"); + ignoredResult = ignoredResult.WithResult(isValid: true, "Validation minimum - ignored because the value is not a number", "minimum"); + + return ignoredResult; + } + + return validationContext; + } + + ValidationContext result = validationContext; + + if ((value.HasJsonElementBacking + ? BinaryJsonNumber.Compare(value.AsJsonElement, Maximum) + : BinaryJsonNumber.Compare(value.AsBinaryJsonNumber, Maximum))<= 0) + { + if (level == ValidationLevel.Verbose) + { + result = result.WithResult(isValid: true, $"Validation maximum - {value} is less than or equal to {Maximum}", "maximum"); + } + } + else + { + if (level >= ValidationLevel.Detailed) + { + result = result.WithResult(isValid: false, $"Validation maximum - {value} is greater than {Maximum}", "maximum"); + } + else if (level >= ValidationLevel.Basic) + { + result = result.WithResult(isValid: false, "Validation maximum - is greater than the required value.", "maximum"); + } + else + { + return ValidationContext.InvalidContext; + } + } + + if ((value.HasJsonElementBacking + ? BinaryJsonNumber.Compare(value.AsJsonElement, Minimum) + : BinaryJsonNumber.Compare(value.AsBinaryJsonNumber, Minimum))>= 0) + { + if (level == ValidationLevel.Verbose) + { + result = result.WithResult(isValid: true, $"Validation minimum - {value} is greater than or equal to {Minimum}", "minimum"); + } + } + else + { + if (level >= ValidationLevel.Detailed) + { + result = result.WithResult(isValid: false, $"Validation minimum - {value} is less than {Minimum}", "minimum"); + } + else if (level >= ValidationLevel.Basic) + { + result = result.WithResult(isValid: false, "Validation minimum - is less than the required value.", "minimum"); + } + else + { + return ValidationContext.InvalidContext; + } + } + return result; + } + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.cs new file mode 100644 index 000000000..9054bf068 --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeNumberEntity.cs @@ -0,0 +1,692 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Buffers; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Corvus.Json; +using Corvus.Json.Internal; + +namespace Sandbox; + +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + /// Generated from JSON Schema. + /// + [System.Text.Json.Serialization.JsonConverter(typeof(Corvus.Json.Internal.JsonValueConverter))] + public readonly partial struct SomeNumberEntity + + { + private readonly Backing backing; + private readonly JsonElement jsonElementBacking; + private readonly BinaryJsonNumber numberBacking; + + /// + /// Initializes a new instance of the struct. + /// + public SomeNumberEntity() + { + this.jsonElementBacking = default; + this.backing = Backing.JsonElement; + this.numberBacking = default; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public SomeNumberEntity(in JsonElement value) + { + this.jsonElementBacking = value; + this.backing = Backing.JsonElement; + this.numberBacking = default; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public SomeNumberEntity(BinaryJsonNumber value) + { + this.backing = Backing.Number; + this.jsonElementBacking = default; + this.numberBacking = value; + } + + /// + /// Gets the schema location from which this type was generated. + /// + public static string SchemaLocation { get; } = "#/properties/someNumber"; + + /// + /// Gets a Null instance. + /// + public static SomeNumberEntity Null { get; } = new(JsonValueHelpers.NullElement); + + /// + /// Gets an Undefined instance. + /// + public static SomeNumberEntity Undefined { get; } + + /// + /// Gets the default instance. + /// + public static SomeNumberEntity DefaultInstance { get; } + + /// + public JsonAny AsAny + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Number) != 0) + { + return new(this.numberBacking); + } + + if ((this.backing & Backing.Null) != 0) + { + return JsonAny.Null; + } + + return JsonAny.Undefined; + } + } + + /// + public JsonElement AsJsonElement + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking; + } + + if ((this.backing & Backing.Number) != 0) + { + return JsonValueHelpers.NumberToJsonElement(this.numberBacking); + } + + if ((this.backing & Backing.Null) != 0) + { + return JsonValueHelpers.NullElement; + } + + return default; + } + } + + /// + JsonString IJsonValue.AsString + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonBoolean IJsonValue.AsBoolean + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + public JsonNumber AsNumber + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Number) != 0) + { + return new(this.numberBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonObject IJsonValue.AsObject + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonArray IJsonValue.AsArray + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + public bool HasJsonElementBacking + { + get + { + return (this.backing & Backing.JsonElement) != 0; + } + } + + /// + public bool HasDotnetBacking + { + get + { + return (this.backing & Backing.Dotnet) != 0; + } + } + + /// + public JsonValueKind ValueKind + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.ValueKind; + } + + if ((this.backing & Backing.Number) != 0) + { + return JsonValueKind.Number; + } + + return JsonValueKind.Undefined; + } + } + + /// + /// Conversion from JsonAny. + /// + /// The value from which to convert. + public static implicit operator SomeNumberEntity(JsonAny value) + { + return value.As(); + } + + /// + /// Conversion to JsonAny. + /// + /// The value from which to convert. + public static implicit operator JsonAny(SomeNumberEntity value) + { + return value.AsAny; + } + + /// + /// Operator ==. + /// + /// The lhs of the operator. + /// The rhs of the operator. + /// + /// True if the values are equal. + /// + public static bool operator ==(in SomeNumberEntity left, in SomeNumberEntity right) + { + return left.Equals(right); + } + + /// + /// Operator !=. + /// + /// The lhs of the operator. + /// The rhs of the operator. + /// + /// True if the values are not equal. + /// + public static bool operator !=(in SomeNumberEntity left, in SomeNumberEntity right) + { + return !left.Equals(right); + } + + /// + /// Gets an instance of the JSON value from a value. + /// + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the . + /// The returned value will have a of if the + /// value cannot be constructed from the given instance (e.g. because they have an incompatible .NET backing type). + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SomeNumberEntity FromJson(in JsonElement value) + { + return new(value); + } + + /// + /// Gets an instance of the JSON value from a value. + /// + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SomeNumberEntity FromAny(in JsonAny value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return value.ValueKind switch + { + JsonValueKind.Number => new(value.AsNumber.AsBinaryJsonNumber), + JsonValueKind.Null => Null, + _ => Undefined, + }; + } + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static SomeNumberEntity IJsonValue.FromBoolean(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static SomeNumberEntity IJsonValue.FromString(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SomeNumberEntity FromNumber(in TValue value) + where TValue : struct, IJsonNumber + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return value.ValueKind switch + { + JsonValueKind.Number => new(value.AsBinaryJsonNumber), + JsonValueKind.Null => Null, + _ => Undefined, + }; + } + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static SomeNumberEntity IJsonValue.FromObject(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static SomeNumberEntity IJsonValue.FromArray(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + + /// + /// Parses the SomeNumberEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeNumberEntity Parse(string source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeNumberEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeNumberEntity Parse(Stream source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeNumberEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeNumberEntity Parse(ReadOnlyMemory source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeNumberEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeNumberEntity Parse(ReadOnlyMemory source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeNumberEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeNumberEntity Parse(ReadOnlySequence source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeNumberEntity. + /// + /// The source of the JSON string to parse. + public static SomeNumberEntity ParseValue(string source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source.AsSpan()); +#endif + } + + /// + /// Parses the SomeNumberEntity. + /// + /// The source of the JSON string to parse. + public static SomeNumberEntity ParseValue(ReadOnlySpan source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source); +#endif + } + + /// + /// Parses the SomeNumberEntity. + /// + /// The source of the JSON string to parse. + public static SomeNumberEntity ParseValue(ReadOnlySpan source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source); +#endif + } + + /// + /// Parses the SomeNumberEntity. + /// + /// The source of the JSON string to parse. + public static SomeNumberEntity ParseValue(ref Utf8JsonReader source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(ref source); +#else + return JsonValueHelpers.ParseValue(ref source); +#endif + } + + /// + /// Gets the value as an instance of the target value. + /// + /// The type of the target. + /// An instance of the target type. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TTarget As() + where TTarget : struct, IJsonValue + { +#if NET8_0_OR_GREATER + if ((this.backing & Backing.JsonElement) != 0) + { + return TTarget.FromJson(this.jsonElementBacking); + } + + if ((this.backing & Backing.Number) != 0) + { + return TTarget.FromNumber(this); + } + + if ((this.backing & Backing.Null) != 0) + { + return TTarget.Null; + } + + return TTarget.Undefined; +#else + return this.As(); +#endif + } + + /// + public override bool Equals(object? obj) + { + return + (obj is IJsonValue jv && this.Equals(jv.As())) || + (obj is null && this.IsNull()); + } + + /// + public bool Equals(in T other) + where T : struct, IJsonValue + { + return this.Equals(other.As()); + } + + /// + /// Equality comparison. + /// + /// The other item with which to compare. + /// if the values were equal. + public bool Equals(in SomeNumberEntity other) + { + JsonValueKind thisKind = this.ValueKind; + JsonValueKind otherKind = other.ValueKind; + if (thisKind != otherKind) + { + return false; + } + + if (thisKind == JsonValueKind.Null || thisKind == JsonValueKind.Undefined) + { + return true; + } + + if (thisKind == JsonValueKind.Number) + { + if (this.backing == Backing.Number && other.backing == Backing.Number) + { + return BinaryJsonNumber.Equals(this.numberBacking, other.numberBacking); + } + + if (this.backing == Backing.Number && other.backing == Backing.JsonElement) + { + return BinaryJsonNumber.Equals(this.numberBacking, other.jsonElementBacking); + } + + if (this.backing == Backing.JsonElement && other.backing == Backing.Number) + { + return BinaryJsonNumber.Equals(this.jsonElementBacking, other.numberBacking); + } + + if (this.jsonElementBacking.TryGetDouble(out double lDouble)) + { + if (other.jsonElementBacking.TryGetDouble(out double rDouble)) + { + return lDouble.Equals(rDouble); + } + } + + if (this.jsonElementBacking.TryGetDecimal(out decimal lDecimal)) + { + if (other.jsonElementBacking.TryGetDecimal(out decimal rDecimal)) + { + return lDecimal.Equals(rDecimal); + } + } + } + + return false; + } + + /// + public void WriteTo(Utf8JsonWriter writer) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Undefined) + { + this.jsonElementBacking.WriteTo(writer); + } + + return; + } + + if ((this.backing & Backing.Number) != 0) + { + this.numberBacking.WriteTo(writer); + + return; + } + + if ((this.backing & Backing.Null) != 0) + { + writer.WriteNullValue(); + + return; + } + } + + /// + public override int GetHashCode() + { + return this.ValueKind switch + { + JsonValueKind.Array => JsonValueHelpers.GetArrayHashCode(((IJsonValue)this).AsArray), + JsonValueKind.Object => JsonValueHelpers.GetObjectHashCode(((IJsonValue)this).AsObject), + JsonValueKind.Number => JsonValueHelpers.GetHashCodeForNumber(this), + JsonValueKind.String => JsonValueHelpers.GetHashCodeForString(((IJsonValue)this).AsString), + JsonValueKind.True => true.GetHashCode(), + JsonValueKind.False => false.GetHashCode(), + JsonValueKind.Null => JsonValueHelpers.NullHashCode, + _ => JsonValueHelpers.UndefinedHashCode, + }; + } + + /// + public override string ToString() + { + return this.Serialize(); + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.String.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.String.cs new file mode 100644 index 000000000..60e950bfb --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.String.cs @@ -0,0 +1,529 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Buffers; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using Corvus.Json; +using Corvus.Json.Internal; + +namespace Sandbox; + +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + /// Generated from JSON Schema. + /// + public readonly partial struct SomeStringEntity +#if NET8_0_OR_GREATER + : IJsonString, + ISpanFormattable +#else + : IJsonString +#endif + { + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public SomeStringEntity(in ReadOnlySpan value) + { + this.backing = Backing.String; + this.jsonElementBacking = default; + this.stringBacking = value.ToString(); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public SomeStringEntity(in ReadOnlySpan value) + { + this.backing = Backing.String; + this.jsonElementBacking = default; + +#if NET8_0_OR_GREATER + this.stringBacking = System.Text.Encoding.UTF8.GetString(value); +#else + byte[] bytes = ArrayPool.Shared.Rent(value.Length); + try + { + value.CopyTo(bytes); + this.stringBacking = System.Text.Encoding.UTF8.GetString(bytes); + } + finally + { + ArrayPool.Shared.Return(bytes); + } +#endif + } + + /// + /// Conversion from . + /// + /// The value from which to convert. + public static implicit operator SomeStringEntity(string value) + { + return new(value); + } + + /// + /// Conversion from JsonString. + /// + /// The value from which to convert. + public static implicit operator SomeStringEntity(JsonString value) + { + if (value.HasDotnetBacking && value.ValueKind == JsonValueKind.String) + { + return new( + (string)value); + } + + return new(value.AsJsonElement); + } + + /// + /// Conversion to JsonString. + /// + /// The value from which to convert. + public static implicit operator JsonString(SomeStringEntity value) + { + return + value.AsString; + } + + /// + /// Conversion to string. + /// + /// The value from which to convert. + /// The value was not a string. + public static explicit operator string(SomeStringEntity value) + { + if ((value.backing & Backing.JsonElement) != 0) + { + if (value.jsonElementBacking.GetString() is string result) + { + return result; + } + + throw new InvalidOperationException(); + } + + if ((value.backing & Backing.String) != 0) + { + return value.stringBacking; + } + + throw new InvalidOperationException(); + } + + /// + /// Concatenate 2 JSON values, producing an instance of the string type SomeStringEntity. + /// + /// The type of the 1st value. + /// The type of the 2nd value. + /// The buffer into which to concatenate the values. + /// The 1st value. + /// The 2nd value. + /// An instance of this string type. + public static SomeStringEntity Concatenate(Span buffer, in T1 value1, in T2 value2) + where T1 : struct, IJsonValue + where T2 : struct, IJsonValue + { + int written = LowAllocJsonUtils.ConcatenateAsUtf8JsonString(buffer, value1, value2); + return ParseValue(buffer[..written]); + } + + /// + /// Concatenate 3 JSON values, producing an instance of the string type SomeStringEntity. + /// + /// The type of the 1st value. + /// The type of the 2nd value. + /// The type of the 3rd value. + /// The buffer into which to concatenate the values. + /// The 1st value. + /// The 2nd value. + /// The 3rd value. + /// An instance of this string type. + public static SomeStringEntity Concatenate(Span buffer, in T1 value1, in T2 value2, in T3 value3) + where T1 : struct, IJsonValue + where T2 : struct, IJsonValue + where T3 : struct, IJsonValue + { + int written = LowAllocJsonUtils.ConcatenateAsUtf8JsonString(buffer, value1, value2, value3); + return ParseValue(buffer[..written]); + } + + /// + /// Concatenate 4 JSON values, producing an instance of the string type SomeStringEntity. + /// + /// The type of the 1st value. + /// The type of the 2nd value. + /// The type of the 3rd value. + /// The type of the 4th value. + /// The buffer into which to concatenate the values. + /// The 1st value. + /// The 2nd value. + /// The 3rd value. + /// The 4th value. + /// An instance of this string type. + public static SomeStringEntity Concatenate(Span buffer, in T1 value1, in T2 value2, in T3 value3, in T4 value4) + where T1 : struct, IJsonValue + where T2 : struct, IJsonValue + where T3 : struct, IJsonValue + where T4 : struct, IJsonValue + { + int written = LowAllocJsonUtils.ConcatenateAsUtf8JsonString(buffer, value1, value2, value3, value4); + return ParseValue(buffer[..written]); + } + + /// + /// Concatenate 5 JSON values, producing an instance of the string type SomeStringEntity. + /// + /// The type of the 1st value. + /// The type of the 2nd value. + /// The type of the 3rd value. + /// The type of the 4th value. + /// The type of the 5th value. + /// The buffer into which to concatenate the values. + /// The 1st value. + /// The 2nd value. + /// The 3rd value. + /// The 4th value. + /// The 5th value. + /// An instance of this string type. + public static SomeStringEntity Concatenate(Span buffer, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5) + where T1 : struct, IJsonValue + where T2 : struct, IJsonValue + where T3 : struct, IJsonValue + where T4 : struct, IJsonValue + where T5 : struct, IJsonValue + { + int written = LowAllocJsonUtils.ConcatenateAsUtf8JsonString(buffer, value1, value2, value3, value4, value5); + return ParseValue(buffer[..written]); + } + + /// + /// Concatenate 6 JSON values, producing an instance of the string type SomeStringEntity. + /// + /// The type of the 1st value. + /// The type of the 2nd value. + /// The type of the 3rd value. + /// The type of the 4th value. + /// The type of the 5th value. + /// The type of the 6th value. + /// The buffer into which to concatenate the values. + /// The 1st value. + /// The 2nd value. + /// The 3rd value. + /// The 4th value. + /// The 5th value. + /// The 6th value. + /// An instance of this string type. + public static SomeStringEntity Concatenate(Span buffer, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6) + where T1 : struct, IJsonValue + where T2 : struct, IJsonValue + where T3 : struct, IJsonValue + where T4 : struct, IJsonValue + where T5 : struct, IJsonValue + where T6 : struct, IJsonValue + { + int written = LowAllocJsonUtils.ConcatenateAsUtf8JsonString(buffer, value1, value2, value3, value4, value5, value6); + return ParseValue(buffer[..written]); + } + + /// + /// Concatenate 7 JSON values, producing an instance of the string type SomeStringEntity. + /// + /// The type of the 1st value. + /// The type of the 2nd value. + /// The type of the 3rd value. + /// The type of the 4th value. + /// The type of the 5th value. + /// The type of the 6th value. + /// The type of the 7th value. + /// The buffer into which to concatenate the values. + /// The 1st value. + /// The 2nd value. + /// The 3rd value. + /// The 4th value. + /// The 5th value. + /// The 6th value. + /// The 7th value. + /// An instance of this string type. + public static SomeStringEntity Concatenate(Span buffer, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7) + where T1 : struct, IJsonValue + where T2 : struct, IJsonValue + where T3 : struct, IJsonValue + where T4 : struct, IJsonValue + where T5 : struct, IJsonValue + where T6 : struct, IJsonValue + where T7 : struct, IJsonValue + { + int written = LowAllocJsonUtils.ConcatenateAsUtf8JsonString(buffer, value1, value2, value3, value4, value5, value6, value7); + return ParseValue(buffer[..written]); + } + + /// + /// Concatenate 8 JSON values, producing an instance of the string type SomeStringEntity. + /// + /// The type of the 1st value. + /// The type of the 2nd value. + /// The type of the 3rd value. + /// The type of the 4th value. + /// The type of the 5th value. + /// The type of the 6th value. + /// The type of the 7th value. + /// The type of the 8th value. + /// The buffer into which to concatenate the values. + /// The 1st value. + /// The 2nd value. + /// The 3rd value. + /// The 4th value. + /// The 5th value. + /// The 6th value. + /// The 7th value. + /// The 8th value. + /// An instance of this string type. + public static SomeStringEntity Concatenate(Span buffer, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8) + where T1 : struct, IJsonValue + where T2 : struct, IJsonValue + where T3 : struct, IJsonValue + where T4 : struct, IJsonValue + where T5 : struct, IJsonValue + where T6 : struct, IJsonValue + where T7 : struct, IJsonValue + where T8 : struct, IJsonValue + { + int written = LowAllocJsonUtils.ConcatenateAsUtf8JsonString(buffer, value1, value2, value3, value4, value5, value6, value7, value8); + return ParseValue(buffer[..written]); + } + + /// + public bool TryGetString([NotNullWhen(true)] out string? value) + { + if ((this.backing & Backing.String) != 0) + { + value = this.stringBacking; + return true; + } + + if ((this.backing & Backing.JsonElement) != 0 && + this.jsonElementBacking.ValueKind == JsonValueKind.String) + { + value = this.jsonElementBacking.GetString(); + return value is not null; + } + + value = null; + return false; + } + + /// + /// Gets the string value. + /// + /// The string if this value represents a string, otherwise null. + public string? GetString() + { + if (this.TryGetString(out string? value)) + { + return value; + } + + return null; + } + + /// + /// Compare to a sequence of characters. + /// + /// The UTF8-encoded character sequence to compare. + /// True if the sequences match. + public bool EqualsUtf8Bytes(ReadOnlySpan utf8Bytes) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind == JsonValueKind.String) + { + return this.jsonElementBacking.ValueEquals(utf8Bytes); + } + } + + if ((this.backing & Backing.String) != 0) + { + int maxCharCount = System.Text.Encoding.UTF8.GetMaxCharCount(utf8Bytes.Length); +#if NET8_0_OR_GREATER + char[]? pooledChars = null; + + Span chars = maxCharCount <= JsonValueHelpers.MaxStackAlloc ? + stackalloc char[maxCharCount] : + (pooledChars = ArrayPool.Shared.Rent(maxCharCount)); + + try + { + int written = System.Text.Encoding.UTF8.GetChars(utf8Bytes, chars); + return chars[..written].SequenceEqual(this.stringBacking); + } + finally + { + if (pooledChars is char[] pc) + { + ArrayPool.Shared.Return(pc); + } + } +#else + char[] chars = ArrayPool.Shared.Rent(maxCharCount); + byte[] bytes = ArrayPool.Shared.Rent(utf8Bytes.Length); + utf8Bytes.CopyTo(bytes); + + try + { + int written = System.Text.Encoding.UTF8.GetChars(bytes, 0, utf8Bytes.Length, chars, 0); + return chars.AsSpan()[..written].SequenceEqual(this.stringBacking.AsSpan()); + } + finally + { + ArrayPool.Shared.Return(chars); + ArrayPool.Shared.Return(bytes); + } +#endif + } + + return false; + } + + /// + /// Compare to a sequence of characters. + /// + /// The character sequence to compare. + /// True if the sequences match. + public bool EqualsString(string chars) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind == JsonValueKind.String) + { + return this.jsonElementBacking.ValueEquals(chars); + } + + return false; + } + + if ((this.backing & Backing.String) != 0) + { + return chars.Equals(this.stringBacking, StringComparison.Ordinal); + } + + return false; + } + + /// + /// Compare to a sequence of characters. + /// + /// The character sequence to compare. + /// True if the sequences match. + public bool EqualsString(ReadOnlySpan chars) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind == JsonValueKind.String) + { + return this.jsonElementBacking.ValueEquals(chars); + } + + return false; + } + + if ((this.backing & Backing.String) != 0) + { +#if NET8_0_OR_GREATER + return chars.SequenceEqual(this.stringBacking); +#else + return chars.SequenceEqual(this.stringBacking.AsSpan()); +#endif + } + + return false; + } + +#if NET8_0_OR_GREATER + /// + public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) + { + if ((this.backing & Backing.String) != 0) + { + int length = Math.Min(destination.Length, this.stringBacking.Length); + this.stringBacking.AsSpan(0, length).CopyTo(destination); + charsWritten = length; + return true; + } + + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind == JsonValueKind.String) + { + char[] buffer = ArrayPool.Shared.Rent(destination.Length); + try + { + bool result = this.jsonElementBacking.TryGetValue(FormatSpan, new CorvusOutput(buffer, destination.Length), out charsWritten); + if (result) + { + buffer.AsSpan(0, charsWritten).CopyTo(destination); + } + + return result; + } + finally + { + ArrayPool.Shared.Return(buffer); + } + } + else + { + string value = this.jsonElementBacking.GetRawText(); + int length = Math.Min(destination.Length, this.stringBacking.Length); + this.stringBacking.AsSpan(0, length).CopyTo(destination); + charsWritten = length; + return true; + } + } + + // We return true from here because we have done our best to format it, and written no characters. + charsWritten = 0; + return true; + + static bool FormatSpan(ReadOnlySpan source, in CorvusOutput output, out int charsWritten) + { + int length = Math.Min(output.Length, source.Length); + source[..length].CopyTo(output.Destination); + charsWritten = length; + return true; + } + } + + /// + public string ToString(string? format, IFormatProvider? formatProvider) + { + // There is no formatting for the string + return this.ToString(); + } +#endif + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.Validate.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.Validate.cs new file mode 100644 index 000000000..43f76ee35 --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.Validate.cs @@ -0,0 +1,171 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Corvus.Json; + +namespace Sandbox; + +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + /// Generated from JSON Schema. + /// + public readonly partial struct SomeStringEntity + { + /// + public ValidationContext Validate(in ValidationContext validationContext, ValidationLevel level = ValidationLevel.Flag) + { + ValidationContext result = validationContext; + if (level > ValidationLevel.Flag && !result.IsUsingResults) + { + result = result.UsingResults(); + } + + if (level > ValidationLevel.Basic) + { + if (!result.IsUsingStack) + { + result = result.UsingStack(); + } + + result = result.PushSchemaLocation("#/properties/someString"); + } + + JsonValueKind valueKind = this.ValueKind; + + result = CorvusValidation.TypeValidationHandler(valueKind, result, level); + + if (level == ValidationLevel.Flag && !result.IsValid) + { + return result; + } + + result = CorvusValidation.StringValidationHandler(this, valueKind, result, level); + + if (level == ValidationLevel.Flag && !result.IsValid) + { + return result; + } + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + + return result; + } + + /// + /// Validation constants for the type. + /// + public static partial class CorvusValidation + { + /// + /// A constant for the minLength keyword. + /// + public static readonly long MinLength = 1; + + /// + /// Core type validation. + /// + /// The of the value to validate. + /// The current validation context. + /// The current validation level. + /// The resulting validation context after validation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ValidationContext TypeValidationHandler( + JsonValueKind valueKind, + in ValidationContext validationContext, + ValidationLevel level = ValidationLevel.Flag) + { + return Corvus.Json.ValidateWithoutCoreType.TypeString(valueKind, validationContext, level, "type"); + } + + /// + /// String validation. + /// + /// The value to validate. + /// The of the value to validate. + /// The current validation context. + /// The current validation level. + /// The resulting validation context after validation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ValidationContext StringValidationHandler( + in SomeStringEntity value, + JsonValueKind valueKind, + in ValidationContext validationContext, + ValidationLevel level = ValidationLevel.Flag) + { + if (valueKind != JsonValueKind.String) + { + if (level == ValidationLevel.Verbose) + { + ValidationContext ignoredResult = validationContext; + ignoredResult = ignoredResult.WithResult(isValid: true, "Validation minLength - ignored because the value is not a string", "minLength"); + + return ignoredResult; + } + + return validationContext; + } + + ValidationContext result = validationContext; + value.TryGetValue(StringValidator, new Corvus.Json.Validate.ValidationContextWrapper(result, level), out result); + + return result; + + static bool StringValidator(ReadOnlySpan input, in Corvus.Json.Validate.ValidationContextWrapper context, out ValidationContext result) + { + int length = Corvus.Json.Validate.CountRunes(input); + result = context.Context; + + if (length >= MinLength) + { + if (context.Level == ValidationLevel.Verbose) + { + result = result.WithResult(isValid: true, validationLocationReducedPathModifier: new JsonReference("minLength"), $"Validation minLength - {input.ToString()} of {length} is greater than or equal to {MinLength}"); + } + } + else + { + if (context.Level == ValidationLevel.Flag) + { + result = context.Context.WithResult(isValid: false); + return true; + } + else if (context.Level >= ValidationLevel.Detailed) + { + result = result.WithResult(isValid: false, validationLocationReducedPathModifier: new JsonReference("minLength"), $"Validation minLength - {input.ToString()} of {length} is less than {MinLength}"); + } + else + { + result = result.WithResult(isValid: false, validationLocationReducedPathModifier: new JsonReference("minLength"), "Validation minLength - is less than the required length."); + } + } + + return true; + } + } + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.cs new file mode 100644 index 000000000..c8a5ab229 --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.SomeStringEntity.cs @@ -0,0 +1,688 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Buffers; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Corvus.Json; +using Corvus.Json.Internal; + +namespace Sandbox; + +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + /// Generated from JSON Schema. + /// + [System.Text.Json.Serialization.JsonConverter(typeof(Corvus.Json.Internal.JsonValueConverter))] + public readonly partial struct SomeStringEntity + + { + private readonly Backing backing; + private readonly JsonElement jsonElementBacking; + private readonly string stringBacking; + + /// + /// Initializes a new instance of the struct. + /// + public SomeStringEntity() + { + this.jsonElementBacking = default; + this.backing = Backing.JsonElement; + this.stringBacking = string.Empty; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public SomeStringEntity(in JsonElement value) + { + this.jsonElementBacking = value; + this.backing = Backing.JsonElement; + this.stringBacking = string.Empty; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public SomeStringEntity(string value) + { + this.backing = Backing.String; + this.jsonElementBacking = default; + this.stringBacking = value; + } + + /// + /// Gets the schema location from which this type was generated. + /// + public static string SchemaLocation { get; } = "#/properties/someString"; + + /// + /// Gets a Null instance. + /// + public static SomeStringEntity Null { get; } = new(JsonValueHelpers.NullElement); + + /// + /// Gets an Undefined instance. + /// + public static SomeStringEntity Undefined { get; } + + /// + /// Gets the default instance. + /// + public static SomeStringEntity DefaultInstance { get; } + + /// + public JsonAny AsAny + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.String) != 0) + { + return new(this.stringBacking); + } + + if ((this.backing & Backing.Null) != 0) + { + return JsonAny.Null; + } + + return JsonAny.Undefined; + } + } + + /// + public JsonElement AsJsonElement + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking; + } + + if ((this.backing & Backing.String) != 0) + { + return JsonValueHelpers.StringToJsonElement(this.stringBacking); + } + + if ((this.backing & Backing.Null) != 0) + { + return JsonValueHelpers.NullElement; + } + + return default; + } + } + + /// + public JsonString AsString + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.String) != 0) + { + return new(this.stringBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonBoolean IJsonValue.AsBoolean + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonNumber IJsonValue.AsNumber + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonObject IJsonValue.AsObject + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonArray IJsonValue.AsArray + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + public bool HasJsonElementBacking + { + get + { + return (this.backing & Backing.JsonElement) != 0; + } + } + + /// + public bool HasDotnetBacking + { + get + { + return (this.backing & Backing.Dotnet) != 0; + } + } + + /// + public JsonValueKind ValueKind + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.ValueKind; + } + + if ((this.backing & Backing.String) != 0) + { + return JsonValueKind.String; + } + + return JsonValueKind.Undefined; + } + } + + /// + /// Conversion from JsonAny. + /// + /// The value from which to convert. + public static implicit operator SomeStringEntity(JsonAny value) + { + return value.As(); + } + + /// + /// Conversion to JsonAny. + /// + /// The value from which to convert. + public static implicit operator JsonAny(SomeStringEntity value) + { + return value.AsAny; + } + + /// + /// Operator ==. + /// + /// The lhs of the operator. + /// The rhs of the operator. + /// + /// True if the values are equal. + /// + public static bool operator ==(in SomeStringEntity left, in SomeStringEntity right) + { + return left.Equals(right); + } + + /// + /// Operator !=. + /// + /// The lhs of the operator. + /// The rhs of the operator. + /// + /// True if the values are not equal. + /// + public static bool operator !=(in SomeStringEntity left, in SomeStringEntity right) + { + return !left.Equals(right); + } + + /// + /// Gets an instance of the JSON value from a value. + /// + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the . + /// The returned value will have a of if the + /// value cannot be constructed from the given instance (e.g. because they have an incompatible .NET backing type). + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SomeStringEntity FromJson(in JsonElement value) + { + return new(value); + } + + /// + /// Gets an instance of the JSON value from a value. + /// + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SomeStringEntity FromAny(in JsonAny value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return value.ValueKind switch + { + JsonValueKind.String => new(value.AsString.GetString()!), + JsonValueKind.Null => Null, + _ => Undefined, + }; + } + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static SomeStringEntity IJsonValue.FromBoolean(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SomeStringEntity FromString(in TValue value) + where TValue : struct, IJsonString + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return value.ValueKind switch + { + JsonValueKind.String => new(value.GetString()!), + JsonValueKind.Null => Null, + _ => Undefined, + }; + } + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static SomeStringEntity IJsonValue.FromNumber(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static SomeStringEntity IJsonValue.FromObject(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static SomeStringEntity IJsonValue.FromArray(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + + /// + /// Parses the SomeStringEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeStringEntity Parse(string source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeStringEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeStringEntity Parse(Stream source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeStringEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeStringEntity Parse(ReadOnlyMemory source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeStringEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeStringEntity Parse(ReadOnlyMemory source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeStringEntity. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static SomeStringEntity Parse(ReadOnlySequence source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the SomeStringEntity. + /// + /// The source of the JSON string to parse. + public static SomeStringEntity ParseValue(string source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source.AsSpan()); +#endif + } + + /// + /// Parses the SomeStringEntity. + /// + /// The source of the JSON string to parse. + public static SomeStringEntity ParseValue(ReadOnlySpan source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source); +#endif + } + + /// + /// Parses the SomeStringEntity. + /// + /// The source of the JSON string to parse. + public static SomeStringEntity ParseValue(ReadOnlySpan source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source); +#endif + } + + /// + /// Parses the SomeStringEntity. + /// + /// The source of the JSON string to parse. + public static SomeStringEntity ParseValue(ref Utf8JsonReader source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(ref source); +#else + return JsonValueHelpers.ParseValue(ref source); +#endif + } + + /// + /// Gets the value as an instance of the target value. + /// + /// The type of the target. + /// An instance of the target type. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TTarget As() + where TTarget : struct, IJsonValue + { +#if NET8_0_OR_GREATER + if ((this.backing & Backing.JsonElement) != 0) + { + return TTarget.FromJson(this.jsonElementBacking); + } + + if ((this.backing & Backing.String) != 0) + { + return TTarget.FromString(this); + } + + if ((this.backing & Backing.Null) != 0) + { + return TTarget.Null; + } + + return TTarget.Undefined; +#else + return this.As(); +#endif + } + + /// + public override bool Equals(object? obj) + { + return + (obj is IJsonValue jv && this.Equals(jv.As())) || + (obj is null && this.IsNull()); + } + + /// + public bool Equals(in T other) + where T : struct, IJsonValue + { + return this.Equals(other.As()); + } + + /// + /// Equality comparison. + /// + /// The other item with which to compare. + /// if the values were equal. + public bool Equals(in SomeStringEntity other) + { + JsonValueKind thisKind = this.ValueKind; + JsonValueKind otherKind = other.ValueKind; + if (thisKind != otherKind) + { + return false; + } + + if (thisKind == JsonValueKind.Null || thisKind == JsonValueKind.Undefined) + { + return true; + } + + if (thisKind == JsonValueKind.String) + { + if (this.backing == Backing.JsonElement) + { + if (other.backing == Backing.String) + { + return this.jsonElementBacking.ValueEquals(other.stringBacking); + } + else + { + other.jsonElementBacking.TryGetValue(CompareValues, this.jsonElementBacking, out bool areEqual); + return areEqual; + } + + } + + if (other.backing == Backing.JsonElement) + { + return other.jsonElementBacking.ValueEquals(this.stringBacking); + } + + return this.stringBacking.Equals(other.stringBacking); + + static bool CompareValues(ReadOnlySpan span, in JsonElement firstItem, out bool value) + { + value = firstItem.ValueEquals(span); + return true; + } + } + + return false; + } + + /// + public void WriteTo(Utf8JsonWriter writer) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Undefined) + { + this.jsonElementBacking.WriteTo(writer); + } + + return; + } + + if ((this.backing & Backing.String) != 0) + { + writer.WriteStringValue(this.stringBacking); + + return; + } + + if ((this.backing & Backing.Null) != 0) + { + writer.WriteNullValue(); + + return; + } + } + + /// + public override int GetHashCode() + { + return this.ValueKind switch + { + JsonValueKind.Array => JsonValueHelpers.GetArrayHashCode(((IJsonValue)this).AsArray), + JsonValueKind.Object => JsonValueHelpers.GetObjectHashCode(((IJsonValue)this).AsObject), + JsonValueKind.Number => JsonValueHelpers.GetHashCodeForNumber(((IJsonValue)this).AsNumber), + JsonValueKind.String => JsonValueHelpers.GetHashCodeForString(this), + JsonValueKind.True => true.GetHashCode(), + JsonValueKind.False => false.GetHashCode(), + JsonValueKind.Null => JsonValueHelpers.NullHashCode, + _ => JsonValueHelpers.UndefinedHashCode, + }; + } + + /// + public override string ToString() + { + return this.Serialize(); + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.Validate.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.Validate.cs new file mode 100644 index 000000000..1523dfc6f --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.Validate.cs @@ -0,0 +1,216 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Corvus.Json; + +namespace Sandbox; +/// +/// Generated from JSON Schema. +/// +public readonly partial struct TestModel +{ + /// + public ValidationContext Validate(in ValidationContext validationContext, ValidationLevel level = ValidationLevel.Flag) + { + ValidationContext result = validationContext; + if (level > ValidationLevel.Flag && !result.IsUsingResults) + { + result = result.UsingResults(); + } + + if (level > ValidationLevel.Basic) + { + if (!result.IsUsingStack) + { + result = result.UsingStack(); + } + + result = result.PushSchemaLocation("test-model.json"); + } + + JsonValueKind valueKind = this.ValueKind; + + result = CorvusValidation.TypeValidationHandler(valueKind, result, level); + + if (level == ValidationLevel.Flag && !result.IsValid) + { + return result; + } + + result = CorvusValidation.ObjectValidationHandler(this, valueKind, result, level); + + if (level == ValidationLevel.Flag && !result.IsValid) + { + return result; + } + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + + return result; + } + + /// + /// Validation constants for the type. + /// + public static partial class CorvusValidation + { + /// + /// Core type validation. + /// + /// The of the value to validate. + /// The current validation context. + /// The current validation level. + /// The resulting validation context after validation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ValidationContext TypeValidationHandler( + JsonValueKind valueKind, + in ValidationContext validationContext, + ValidationLevel level = ValidationLevel.Flag) + { + return Corvus.Json.ValidateWithoutCoreType.TypeObject(valueKind, validationContext, level, "type"); + } + + /// + /// Object validation. + /// + /// The value to validate. + /// The of the value to validate. + /// The current validation context. + /// The current validation level. + /// The resulting validation context after validation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ValidationContext ObjectValidationHandler( + in TestModel value, + JsonValueKind valueKind, + in ValidationContext validationContext, + ValidationLevel level = ValidationLevel.Flag) + { + ValidationContext result = validationContext; + if (valueKind != JsonValueKind.Object) + { + if (level == ValidationLevel.Verbose) + { + ValidationContext ignoredResult = validationContext; + ignoredResult = ignoredResult.WithResult(isValid: true, "Validation properties - ignored because the value is not an object", "properties"); + + return ignoredResult; + } + + return validationContext; + } + + int propertyCount = 0; + foreach (JsonObjectProperty property in value.EnumerateObject()) + { + if (property.NameEquals(JsonPropertyNames.SomeArrayUtf8, JsonPropertyNames.SomeArray)) + { + result = result.WithLocalProperty(propertyCount); + if (level > ValidationLevel.Basic) + { + result = result.PushValidationLocationReducedPathModifierAndProperty(new("#/properties/someArray"), JsonPropertyNames.SomeArray); + } + + ValidationContext propertyResult = property.Value.As().Validate(result.CreateChildContext(), level); + if (level == ValidationLevel.Flag && !propertyResult.IsValid) + { + return propertyResult; + } + + result = result.MergeResults(propertyResult.IsValid, level, propertyResult); + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + } + else if (property.NameEquals(JsonPropertyNames.SomeBoolUtf8, JsonPropertyNames.SomeBool)) + { + result = result.WithLocalProperty(propertyCount); + if (level > ValidationLevel.Basic) + { + result = result.PushValidationLocationReducedPathModifierAndProperty(new("#/properties/someBool"), JsonPropertyNames.SomeBool); + } + + ValidationContext propertyResult = property.Value.As().Validate(result.CreateChildContext(), level); + if (level == ValidationLevel.Flag && !propertyResult.IsValid) + { + return propertyResult; + } + + result = result.MergeResults(propertyResult.IsValid, level, propertyResult); + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + } + else if (property.NameEquals(JsonPropertyNames.SomeNumberUtf8, JsonPropertyNames.SomeNumber)) + { + result = result.WithLocalProperty(propertyCount); + if (level > ValidationLevel.Basic) + { + result = result.PushValidationLocationReducedPathModifierAndProperty(new("#/properties/someNumber"), JsonPropertyNames.SomeNumber); + } + + ValidationContext propertyResult = property.Value.As().Validate(result.CreateChildContext(), level); + if (level == ValidationLevel.Flag && !propertyResult.IsValid) + { + return propertyResult; + } + + result = result.MergeResults(propertyResult.IsValid, level, propertyResult); + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + } + else if (property.NameEquals(JsonPropertyNames.SomeStringUtf8, JsonPropertyNames.SomeString)) + { + result = result.WithLocalProperty(propertyCount); + if (level > ValidationLevel.Basic) + { + result = result.PushValidationLocationReducedPathModifierAndProperty(new("#/properties/someString"), JsonPropertyNames.SomeString); + } + + ValidationContext propertyResult = property.Value.As().Validate(result.CreateChildContext(), level); + if (level == ValidationLevel.Flag && !propertyResult.IsValid) + { + return propertyResult; + } + + result = result.MergeResults(propertyResult.IsValid, level, propertyResult); + + if (level > ValidationLevel.Basic) + { + result = result.PopLocation(); + } + } + + propertyCount++; + } + + return result; + } + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.cs b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.cs new file mode 100644 index 000000000..15481d81c --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Model/TestModel.cs @@ -0,0 +1,678 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#nullable enable + +using global::System; +using global::System.Collections.Generic; +using global::System.IO; +using global::System.Linq; +using global::System.Net.Http; +using global::System.Threading; +using global::System.Threading.Tasks; +using System.Buffers; +using System.Collections.Immutable; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Corvus.Json; +using Corvus.Json.Internal; + +namespace Sandbox; +/// +/// Generated from JSON Schema. +/// +[System.Text.Json.Serialization.JsonConverter(typeof(Corvus.Json.Internal.JsonValueConverter))] +public readonly partial struct TestModel + +{ + private readonly Backing backing; + private readonly JsonElement jsonElementBacking; + private readonly ImmutableList objectBacking; + + /// + /// Initializes a new instance of the struct. + /// + public TestModel() + { + this.jsonElementBacking = default; + this.backing = Backing.JsonElement; + this.objectBacking = ImmutableList.Empty; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public TestModel(in JsonElement value) + { + this.jsonElementBacking = value; + this.backing = Backing.JsonElement; + this.objectBacking = ImmutableList.Empty; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The value from which to construct the instance. + public TestModel(ImmutableList value) + { + this.backing = Backing.Object; + this.jsonElementBacking = default; + this.objectBacking = value; + } + + /// + /// Gets the schema location from which this type was generated. + /// + public static string SchemaLocation { get; } = "test-model.json"; + + /// + /// Gets a Null instance. + /// + public static TestModel Null { get; } = new(JsonValueHelpers.NullElement); + + /// + /// Gets an Undefined instance. + /// + public static TestModel Undefined { get; } + + /// + /// Gets the default instance. + /// + public static TestModel DefaultInstance { get; } + + /// + public JsonAny AsAny + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Object) != 0) + { + return new(this.objectBacking); + } + + if ((this.backing & Backing.Null) != 0) + { + return JsonAny.Null; + } + + return JsonAny.Undefined; + } + } + + /// + public JsonElement AsJsonElement + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking; + } + + if ((this.backing & Backing.Object) != 0) + { + return JsonValueHelpers.ObjectToJsonElement(this.objectBacking); + } + + if ((this.backing & Backing.Null) != 0) + { + return JsonValueHelpers.NullElement; + } + + return default; + } + } + + /// + JsonString IJsonValue.AsString + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonBoolean IJsonValue.AsBoolean + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonNumber IJsonValue.AsNumber + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + public JsonObject AsObject + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + if ((this.backing & Backing.Object) != 0) + { + return new(this.objectBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + JsonArray IJsonValue.AsArray + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return new(this.jsonElementBacking); + } + + throw new InvalidOperationException(); + } + } + + /// + public bool HasJsonElementBacking + { + get + { + return (this.backing & Backing.JsonElement) != 0; + } + } + + /// + public bool HasDotnetBacking + { + get + { + return (this.backing & Backing.Dotnet) != 0; + } + } + + /// + public JsonValueKind ValueKind + { + get + { + if ((this.backing & Backing.JsonElement) != 0) + { + return this.jsonElementBacking.ValueKind; + } + + if ((this.backing & Backing.Object) != 0) + { + return JsonValueKind.Object; + } + + return JsonValueKind.Undefined; + } + } + + /// + /// Conversion from JsonAny. + /// + /// The value from which to convert. + public static implicit operator TestModel(JsonAny value) + { + return value.As(); + } + + /// + /// Conversion to JsonAny. + /// + /// The value from which to convert. + public static implicit operator JsonAny(TestModel value) + { + return value.AsAny; + } + + /// + /// Operator ==. + /// + /// The lhs of the operator. + /// The rhs of the operator. + /// + /// True if the values are equal. + /// + public static bool operator ==(in TestModel left, in TestModel right) + { + return left.Equals(right); + } + + /// + /// Operator !=. + /// + /// The lhs of the operator. + /// The rhs of the operator. + /// + /// True if the values are not equal. + /// + public static bool operator !=(in TestModel left, in TestModel right) + { + return !left.Equals(right); + } + + /// + /// Gets an instance of the JSON value from a value. + /// + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the . + /// The returned value will have a of if the + /// value cannot be constructed from the given instance (e.g. because they have an incompatible .NET backing type). + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TestModel FromJson(in JsonElement value) + { + return new(value); + } + + /// + /// Gets an instance of the JSON value from a value. + /// + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TestModel FromAny(in JsonAny value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return value.ValueKind switch + { + JsonValueKind.Object => new(value.AsObject.AsPropertyBacking()), + JsonValueKind.Null => Null, + _ => Undefined, + }; + } + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static TestModel IJsonValue.FromBoolean(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static TestModel IJsonValue.FromString(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static TestModel IJsonValue.FromNumber(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TestModel FromObject(in TValue value) + where TValue : struct, IJsonObject + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return value.ValueKind switch + { + JsonValueKind.Object => new(value.AsPropertyBacking()), + JsonValueKind.Null => Null, + _ => Undefined, + }; + } + +#if NET8_0_OR_GREATER + /// + /// Gets an instance of the JSON value from the provided value. + /// + /// The type of the value. + /// The value from which to instantiate the instance. + /// An instance of this type, initialized from the provided value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static TestModel IJsonValue.FromArray(in TValue value) + { + if (value.HasJsonElementBacking) + { + return new(value.AsJsonElement); + } + + return Undefined; + } +#endif + + /// + /// Parses the TestModel. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static TestModel Parse(string source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the TestModel. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static TestModel Parse(Stream source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the TestModel. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static TestModel Parse(ReadOnlyMemory source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the TestModel. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static TestModel Parse(ReadOnlyMemory source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the TestModel. + /// + /// The source of the JSON string to parse. + /// The (optional) JsonDocumentOptions. + public static TestModel Parse(ReadOnlySequence source, JsonDocumentOptions options = default) + { + using var jsonDocument = JsonDocument.Parse(source, options); + return new(jsonDocument.RootElement.Clone()); + } + + /// + /// Parses the TestModel. + /// + /// The source of the JSON string to parse. + public static TestModel ParseValue(string source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source.AsSpan()); +#endif + } + + /// + /// Parses the TestModel. + /// + /// The source of the JSON string to parse. + public static TestModel ParseValue(ReadOnlySpan source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source); +#endif + } + + /// + /// Parses the TestModel. + /// + /// The source of the JSON string to parse. + public static TestModel ParseValue(ReadOnlySpan source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(source); +#else + return JsonValueHelpers.ParseValue(source); +#endif + } + + /// + /// Parses the TestModel. + /// + /// The source of the JSON string to parse. + public static TestModel ParseValue(ref Utf8JsonReader source) + { +#if NET8_0_OR_GREATER + return IJsonValue.ParseValue(ref source); +#else + return JsonValueHelpers.ParseValue(ref source); +#endif + } + + /// + /// Gets the value as an instance of the target value. + /// + /// The type of the target. + /// An instance of the target type. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TTarget As() + where TTarget : struct, IJsonValue + { +#if NET8_0_OR_GREATER + if ((this.backing & Backing.JsonElement) != 0) + { + return TTarget.FromJson(this.jsonElementBacking); + } + + if ((this.backing & Backing.Object) != 0) + { + return TTarget.FromObject(this); + } + + if ((this.backing & Backing.Null) != 0) + { + return TTarget.Null; + } + + return TTarget.Undefined; +#else + return this.As(); +#endif + } + + /// + public override bool Equals(object? obj) + { + return + (obj is IJsonValue jv && this.Equals(jv.As())) || + (obj is null && this.IsNull()); + } + + /// + public bool Equals(in T other) + where T : struct, IJsonValue + { + return this.Equals(other.As()); + } + + /// + /// Equality comparison. + /// + /// The other item with which to compare. + /// if the values were equal. + public bool Equals(in TestModel other) + { + JsonValueKind thisKind = this.ValueKind; + JsonValueKind otherKind = other.ValueKind; + if (thisKind != otherKind) + { + return false; + } + + if (thisKind == JsonValueKind.Null || thisKind == JsonValueKind.Undefined) + { + return true; + } + + if (thisKind == JsonValueKind.Object) + { + int count = 0; + foreach (JsonObjectProperty property in this.EnumerateObject()) + { + if (!other.TryGetProperty(property.Name, out JsonAny value) || !property.Value.Equals(value)) + { + return false; + } + + count++; + } + + int otherCount = 0; + foreach (JsonObjectProperty otherProperty in other.EnumerateObject()) + { + otherCount++; + if (otherCount > count) + { + return false; + } + } + + return count == otherCount; + } + + return false; + } + + /// + public void WriteTo(Utf8JsonWriter writer) + { + if ((this.backing & Backing.JsonElement) != 0) + { + if (this.jsonElementBacking.ValueKind != JsonValueKind.Undefined) + { + this.jsonElementBacking.WriteTo(writer); + } + + return; + } + + if ((this.backing & Backing.Object) != 0) + { + JsonValueHelpers.WriteProperties(this.objectBacking, writer); + + return; + } + + if ((this.backing & Backing.Null) != 0) + { + writer.WriteNullValue(); + + return; + } + } + + /// + public override int GetHashCode() + { + return this.ValueKind switch + { + JsonValueKind.Array => JsonValueHelpers.GetArrayHashCode(((IJsonValue)this).AsArray), + JsonValueKind.Object => JsonValueHelpers.GetObjectHashCode(this), + JsonValueKind.Number => JsonValueHelpers.GetHashCodeForNumber(((IJsonValue)this).AsNumber), + JsonValueKind.String => JsonValueHelpers.GetHashCodeForString(((IJsonValue)this).AsString), + JsonValueKind.True => true.GetHashCode(), + JsonValueKind.False => false.GetHashCode(), + JsonValueKind.Null => JsonValueHelpers.NullHashCode, + _ => JsonValueHelpers.UndefinedHashCode, + }; + } + + /// + public override string ToString() + { + return this.Serialize(); + } +} diff --git a/Solutions/Sandbox.NoGlobalUsings/Program.cs b/Solutions/Sandbox.NoGlobalUsings/Program.cs new file mode 100644 index 000000000..522cbccdb --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Program.cs @@ -0,0 +1,7 @@ +using System; +using Sandbox; + +var model = TestModel.Parse("{}"); + +Console.WriteLine(model); +Console.ReadLine(); \ No newline at end of file diff --git a/Solutions/Sandbox.NoGlobalUsings/Sandbox.NoGlobalUsings.csproj b/Solutions/Sandbox.NoGlobalUsings/Sandbox.NoGlobalUsings.csproj new file mode 100644 index 000000000..ca031869e --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/Sandbox.NoGlobalUsings.csproj @@ -0,0 +1,39 @@ + + + + Exe + net8.0 + Latest + disable + enable + false + true + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + diff --git a/Solutions/Sandbox.NoGlobalUsings/test-model.json b/Solutions/Sandbox.NoGlobalUsings/test-model.json new file mode 100644 index 000000000..c8f437e19 --- /dev/null +++ b/Solutions/Sandbox.NoGlobalUsings/test-model.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "someArray": { + "type": "array", + "items": { + "type": "string" + } + }, + "someBool": { + "type": "boolean" + }, + "someNumber": { + "type": "number", + "minimum": 0, + "maximum": 100 + }, + "someString": { + "type": "string", + "minLength": 1 + } + } +} diff --git a/Solutions/generatetypes-release.ps1 b/Solutions/generatetypes-release.ps1 index 3bac898d9..b364a7a4d 100644 --- a/Solutions/generatetypes-release.ps1 +++ b/Solutions/generatetypes-release.ps1 @@ -22,4 +22,6 @@ $toolPath = './Corvus.Json.CodeGenerator/bin/Release/net8.0/Corvus.Json.JsonSche & $toolPath config ./coretypesgeneratorconfig.json -& $toolPath --optionalAsNullable NullOrUndefined --disableNamingHeuristic DocumentationNameHeuristic --rootNamespace Corvus.Json.CodeGenerator --outputPath .\Corvus.Json.CodeGenerator\Model\ .\Corvus.Json.CodeGenerator\generator-config.json \ No newline at end of file +& $toolPath --optionalAsNullable NullOrUndefined --disableNamingHeuristic DocumentationNameHeuristic --rootNamespace Corvus.Json.CodeGenerator --outputPath .\Corvus.Json.CodeGenerator\Model\ .\Corvus.Json.CodeGenerator\generator-config.json + +& $toolPath --addExplicitUsings --optionalAsNullable NullOrUndefined --disableNamingHeuristic DocumentationNameHeuristic --rootNamespace Sandbox --outputPath .\Sandbox.NoGlobalUsings\Model .\Sandbox.NoGlobalUsings\test-model.json diff --git a/Solutions/generatetypes.ps1 b/Solutions/generatetypes.ps1 index 84bcfca52..4ae8688d5 100644 --- a/Solutions/generatetypes.ps1 +++ b/Solutions/generatetypes.ps1 @@ -23,3 +23,5 @@ $toolPath = './Corvus.Json.CodeGenerator/bin/Debug/net8.0/Corvus.Json.JsonSchema & $toolPath config ./coretypesgeneratorconfig.json & $toolPath --optionalAsNullable NullOrUndefined --disableNamingHeuristic DocumentationNameHeuristic --rootNamespace Corvus.Json.CodeGenerator --outputPath .\Corvus.Json.CodeGenerator\Model\ .\Corvus.Json.CodeGenerator\generator-config.json + +& $toolPath --addExplicitUsings --optionalAsNullable NullOrUndefined --disableNamingHeuristic DocumentationNameHeuristic --rootNamespace Sandbox --outputPath .\Sandbox.NoGlobalUsings\Model .\Sandbox.NoGlobalUsings\test-model.json