namespace Json2CSharpCodeGenerator.Lib;
public interface IJsonClassGeneratorConfig
{
///
/// The C# namespace or Java package that the generated types will reside in.
/// by default. If null/empty/whitespace then no enclosing namespace will be written in the output.
///
string Namespace { get; set; }
///
/// The C# namespace or Java package that "secondary" generated types will reside in.
/// by default.
///
string SecondaryNamespace { get; set; }
OutputTypes OutputType { get; set; }
OutputCollectionType CollectionType { get; set; }
/// Options contained within are only respected when == .
MutableClassConfig MutableClasses { get; }
JsonLibrary AttributeLibrary { get; set; }
JsonPropertyAttributeUsage AttributeUsage { get; set; }
bool InternalVisibility { get; set; }
bool NoHelperClass { get; set; }
///
/// When true, then the generated C# and VB.NET classes will have PascalCase property names, which means that [JsonProperty] or [JsonPropertyName] will be applied to all properties if the source JSON uses camelCase names, regardless of .
/// When false, then the generated C# and VB.NET classes' property names will use the same names as the source JSON (except when a JSON property name cannot be represented by a C# identifier).
///
bool UsePascalCase { get; set; }
bool UseNestedClasses { get; set; }
/// Name of the outer class. Only used when == .
string MainClass { get; set; }
/// When , then will be applied to generated types.
bool ApplyObfuscationAttributes { get; set; }
// bool SingleFile { get; set; }
bool UseThisKeyWord { get; set; }
ICodeBuilder CodeWriter { get; set; }
bool AlwaysUseNullableValues { get; set; }
bool ExamplesInDocumentation { get; set; }
bool RemoveToJson { get; set; }
bool RemoveFromJson { get; set; }
bool RemoveConstructors { get; set; }
}
public enum OutputTypes
{
///
/// C#: Mutable class types.
/// VB.NET: Mutable Class types.
/// Java: Mutable Bean class
///
MutableClass,
///
/// C#: Immutable class types. Using [JsonConstructor].
/// VB.NET: Immutable Class types. Using [JsonConstructor].
/// Java: Not yet implemented. TODO.
///
ImmutableClass,
///
/// C#: Immutable record types.
/// VB.NET: Not supported.
/// Java: Not supported.
///
ImmutableRecord
}
public enum OutputCollectionType
{
/// Expose collections as T[].
Array,
///
/// C#/VB.NET: Expose collections as .
/// Java: Uses ArrayList<T>
///
MutableList,
///
/// C#/VB.NET: Expose collections as .
/// Java: Not supported.
///
IReadOnlyList,
///
/// C#/VB.NET: Expose collections as System.Collections.Immutable.ImmutableArray<T>.
/// Java: Not supported.
///
/// ImmutableArray is preferred over ImmutableList when append functionality isn't required.
ImmutableArray
}
public enum OutputMembers
{
/// C# and VB.NET: Uses auto-properties. Java: uses getter/setter methods.
AsProperties,
AsPublicFields,
// AsPublicPropertiesOverPrivateFields // TODO
}
public enum JsonLibrary
{
/// Use the on generated C# class properties.
NewtonsoftJson,
/// Use the [JsonPropertyName] attribute on generated C# class properties.
SystemTextJson
}
public enum JsonPropertyAttributeUsage
{
/// The [JsonProperty] or [JsonPropertyName] attributes will be applied to all properties.
Always,
/// The [JsonProperty] or [JsonPropertyName] attributes will only be applied to properties with names that cannot be expressed as C# identifiers.
OnlyWhenNecessary
}
public class MutableClassConfig
{
///
/// When , then all properties for collections are read-only, though the actual collection-type can still be mutable. e.g. public List<String> StringValues { get; }
/// When , then all properties for collections are read-only, though the actual collection-type can still be mutable. e.g. public List<String> StringValues { get; set; }
/// Default is .
///
public bool ReadOnlyCollectionProperties { get; set; }
public OutputMembers Members { get; set; } = OutputMembers.AsProperties;
}
public static class JsonClassGeneratorConfigExtensions
{
///
/// Never returns . Returns either:
///
/// - "[JsonPropertyName(".")]" (for System.Text.Json).
/// - "[JsonProperty(".")]" (for Newtonsoft.Json).
/// - "[property: JsonPropertyName(".")]" (for System.Text.Json) when is .
/// - "[property: JsonProperty(".")]" (for Newtonsoft.Json) when is .
/// - An empty string depending on and .
///
///
/// Required. Cannot be .
/// Required. Cannot be .
///
public static string GetCSharpJsonAttributeCode(this IJsonClassGeneratorConfig config, FieldInfo field)
{
if (config is null)
throw new ArgumentNullException(nameof(config));
if (field is null)
throw new ArgumentNullException(nameof(field));
//
if (UsePropertyAttribute(config, field))
{
bool usingRecordTypes = config.OutputType == OutputTypes.ImmutableRecord;
string attributeTarget = usingRecordTypes ? "property: " : string.Empty;
return config.AttributeLibrary switch
{
JsonLibrary.NewtonsoftJson => $"[{attributeTarget}JsonProperty(\"{field.JsonMemberName}\")]",
JsonLibrary.SystemTextJson => $"[{attributeTarget}JsonPropertyName(\"{field.JsonMemberName}\")]",
_ => throw new InvalidOperationException("Unrecognized " + nameof(config.AttributeLibrary) + " value: " + config.AttributeLibrary),
};
}
else
{
return string.Empty;
}
}
private static bool UsePropertyAttribute(IJsonClassGeneratorConfig config, FieldInfo field)
{
return config.AttributeUsage switch
{
JsonPropertyAttributeUsage.Always => true,
JsonPropertyAttributeUsage.OnlyWhenNecessary => field.ContainsSpecialChars,
_ => throw new InvalidOperationException("Unrecognized " + nameof(config.AttributeUsage) + " value: " + config.AttributeUsage),
};
}
public static bool HasNamespace(this IJsonClassGeneratorConfig config) => !string.IsNullOrEmpty(config.Namespace);
}