using System.Text; namespace Json2CSharpCodeGenerator.Lib.CodeWriters; public class PythonCodeWriter : ICodeBuilder { public string FileExtension => throw new NotImplementedException(); public string DisplayName => throw new NotImplementedException(); public IReadOnlyCollection ReservedKeywords => throw new NotImplementedException(); public string GetTypeName(JsonType type, IJsonClassGeneratorConfig config) { return type.Type switch { JsonTypeEnum.Anything => "object", JsonTypeEnum.Array => GetCollectionTypeName(elementTypeName: GetTypeName(type.InternalType, config), config.CollectionType), // case JsonTypeEnum.Dictionary: return "Dictionary"; JsonTypeEnum.Boolean => "bool", JsonTypeEnum.Float => "float", JsonTypeEnum.Integer => "int", JsonTypeEnum.Long => "float", //case JsonTypeEnum.Date: return "DateTime"; // Do Later JsonTypeEnum.Date => "str", JsonTypeEnum.NonConstrained => "object", // case JsonTypeEnum.NullableBoolean: return "bool?"; //case JsonTypeEnum.NullableFloat: return "double?"; //case JsonTypeEnum.NullableInteger: return "int?"; //case JsonTypeEnum.NullableLong: return "long?"; //case JsonTypeEnum.NullableDate: return "DateTime?"; //case JsonTypeEnum.NullableSomething: return "object"; JsonTypeEnum.Object => type.NewAssignedName, JsonTypeEnum.String => "str", _ => throw new NotSupportedException("Unsupported json type: " + type.Type), }; } public string GetTypeFunctionName(JsonType type, IJsonClassGeneratorConfig config) { return type.Type switch { JsonTypeEnum.Anything => "", JsonTypeEnum.Array => "[" + type.InternalType.NewAssignedName + ".from_dict(y) for y in {0}]", // case JsonTypeEnum.Dictionary: return "Dictionary"; JsonTypeEnum.Boolean => "", JsonTypeEnum.Float => "float({0})", JsonTypeEnum.Integer => "int({0})", JsonTypeEnum.Long => "float({0})", //case JsonTypeEnum.Date: return "DateTime"; // Do Later JsonTypeEnum.Date => "str({0})", JsonTypeEnum.NonConstrained => "", // case JsonTypeEnum.NullableBoolean: return "bool?"; //case JsonTypeEnum.NullableFloat: return "double?"; //case JsonTypeEnum.NullableInteger: return "int?"; //case JsonTypeEnum.NullableLong: return "long?"; //case JsonTypeEnum.NullableDate: return "DateTime?"; //case JsonTypeEnum.NullableSomething: return "object"; JsonTypeEnum.Object => type.NewAssignedName + ".from_dict({0})", JsonTypeEnum.String => "str({0})", _ => throw new NotSupportedException("Unsupported json type: " + type.Type), }; } public bool IsReservedKeyword(string word) => throw new NotImplementedException(); public void WriteClass(IJsonClassGeneratorConfig config, StringBuilder sw, JsonType type) { string className = type.AssignedName; _ = sw.AppendLine("@dataclass"); _ = sw.AppendFormat("class {0}:{1}", className, Environment.NewLine); WriteClassMembers(config, sw, type, ""); _ = sw.AppendLine(); } public void WriteClassMembers(IJsonClassGeneratorConfig config, StringBuilder sw, JsonType type, string prefix) { StringBuilder fields = new(); StringBuilder mappingFunction = new(); foreach (FieldInfo field in type.Fields) { _ = field.MemberName; string propertyAttribute = field.JsonMemberName; string internalPropertyAttribute = "_" + propertyAttribute; _ = sw.AppendFormat(" {0}: {1}{2}", propertyAttribute, field.Type.GetTypeName(), Environment.NewLine); string mappingFragment = string.Format("obj.get(\"{0}\")", propertyAttribute); string mappingFragment2 = string.Format(GetTypeFunctionName(field.Type, config), mappingFragment); string mappingString = string.Format(" {0} = {1}", internalPropertyAttribute, mappingFragment2); _ = mappingFunction.AppendLine(mappingString); _ = fields.Append(internalPropertyAttribute + ", "); } // Remove trailing comma fields.Length--; fields.Length--; // Write Dictionnary Mapping Functions _ = sw.AppendLine(); _ = sw.AppendLine(" @staticmethod"); _ = sw.AppendLine(string.Format(" def from_dict(obj: Any) -> '{0}':", type.AssignedName)); _ = sw.Append(mappingFunction.ToString()); _ = sw.AppendLine(string.Format(" return {0}({1})", type.AssignedName, fields.ToString())); } public void WriteDeserializationComment(IJsonClassGeneratorConfig config, StringBuilder sw, bool rootIsArray = false) { return; } public void WriteFileEnd(IJsonClassGeneratorConfig config, StringBuilder sw) { _ = sw.Insert(0, "9 json" + Environment.NewLine); _ = sw.Insert(0, "from dataclasses import dataclass" + Environment.NewLine); _ = sw.Insert(0, "from typing import Any" + Environment.NewLine); if (sw.ToString().Contains("List")) _ = sw.Insert(0, string.Format("from typing import List{0}", Environment.NewLine)); _ = sw.AppendLine("# Example Usage"); _ = sw.AppendLine("# jsonstring = json.loads(myjsonstring)"); _ = sw.AppendLine("# root = Root.from_dict(jsonstring)"); return; } public void WriteFileStart(IJsonClassGeneratorConfig config, StringBuilder sw) { return; } public void WriteNamespaceEnd(IJsonClassGeneratorConfig config, StringBuilder sw, bool root) { return; } public void WriteNamespaceStart(IJsonClassGeneratorConfig config, StringBuilder sw, bool root) { return; } private static string GetCollectionTypeName(string elementTypeName, OutputCollectionType type) { return type switch { //case OutputCollectionType.Array: return elementTypeName + "[]"; OutputCollectionType.Array => "List[" + elementTypeName + "]", OutputCollectionType.MutableList => "List[" + elementTypeName + "]", // case OutputCollectionType.IReadOnlyList: return "IReadOnlyList<" + elementTypeName + ">"; // case OutputCollectionType.ImmutableArray: return "ImmutableArray<" + elementTypeName + ">"; _ => throw new ArgumentOutOfRangeException(paramName: nameof(type), actualValue: type, message: "Invalid " + nameof(OutputCollectionType) + " enum value."), }; } }