135 lines
No EOL
3.2 KiB
Beef
135 lines
No EOL
3.2 KiB
Beef
namespace Bofa.Serialization;
|
|
|
|
using System;
|
|
using System.Reflection;
|
|
|
|
using Bofa;
|
|
|
|
[AttributeUsage(.Struct | .Class)]
|
|
struct BofaSerializeAttribute : Attribute, IOnTypeInit
|
|
{
|
|
private bool Strict;
|
|
public this(bool pStrict = false)
|
|
{
|
|
Strict = pStrict;
|
|
}
|
|
|
|
[Comptime]
|
|
public void OnTypeInit(Type type, Self* prev)
|
|
{
|
|
String serializeString = scope .("public bool Serialize(Bofa b)\n{\n");
|
|
String deserializeString = scope .("public bool Deserialize(Bofa b)\n{\n");
|
|
|
|
serializeString.Append("""
|
|
b.Type = .Object;
|
|
b.Value.Object = new .();
|
|
b.Typename = "Object";
|
|
Bofa toAdd;
|
|
|
|
""");
|
|
|
|
deserializeString.Append("""
|
|
if(b.Type != .Object)
|
|
return false;
|
|
|
|
""");
|
|
|
|
|
|
var fields = type.GetFields();
|
|
for(var f in fields)
|
|
{
|
|
if(!f.IsPublic && !f.HasCustomAttribute<BofaIncludeAttribute>())
|
|
continue;
|
|
|
|
bool hasIFace = false;
|
|
for(var i in f.FieldType.Interfaces)
|
|
if(i == typeof(IBofaParseable))
|
|
hasIFace = true;
|
|
|
|
//Hardcoded stuff
|
|
if(f.FieldType == typeof(int))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(int8))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(int16))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(int32))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(int64))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(uint))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(uint8))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(uint16))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(uint32))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(uint64))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(char8))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(char16))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(char32))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(float))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(double))
|
|
hasIFace = true;
|
|
else if(f.FieldType == typeof(System.Security.Cryptography.SHA256Hash))
|
|
hasIFace = true;
|
|
|
|
if(!hasIFace)
|
|
continue;
|
|
|
|
|
|
StringView name;
|
|
name = f.Name;
|
|
if(f.HasCustomAttribute<BofaIncludeAttribute>() && f.GetCustomAttribute<BofaIncludeAttribute>() case .Ok(let attr))
|
|
name = attr.Name;
|
|
|
|
var required = f.HasCustomAttribute<BofaRequiredAttribute>() || Strict;
|
|
|
|
serializeString.Append(scope $"""
|
|
toAdd = new .();
|
|
toAdd.Name = "{name}";
|
|
if(!{f.Name}.Serialize(toAdd))
|
|
\{
|
|
delete toAdd;
|
|
{required ? "return false;" : ""}
|
|
\}
|
|
else
|
|
b.Value.Object.Add("{name}", toAdd);
|
|
""");
|
|
|
|
if(required)
|
|
{
|
|
deserializeString.Append((scope $"""
|
|
if(!b.Value.Object.ContainsKey("{name}"))
|
|
return false;
|
|
if(!{f.Name}.Deserialize(b.Value.Object["{name}"]))
|
|
return false;
|
|
|
|
"""));
|
|
}
|
|
else
|
|
{
|
|
deserializeString.Append(scope $"""
|
|
if(b.Value.Object.ContainsKey("{name}"))
|
|
{f.Name}.Deserialize(b.Value.Object["{name}"]);
|
|
|
|
""");
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
serializeString.Append("\n\treturn true;\n}\n");
|
|
deserializeString.Append("\n\treturn true;\n}\n");
|
|
Compiler.EmitTypeBody(type, serializeString);
|
|
Compiler.EmitTypeBody(type, deserializeString);
|
|
Compiler.EmitAddInterface(type, typeof(IBofaParseable));
|
|
}
|
|
} |