2022-08-13 13:01:47 -07:00

155 lines
6.8 KiB
C#

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<string> 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<string, " + this.GetTypeName(type.InternalType, config) + ">";
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<string, " + this.GetTypeName(type.InternalType, config) + ">";
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."),
};
}
}