Skip to content

Commit

Permalink
Merge pull request #14 from Carnagion/development
Browse files Browse the repository at this point in the history
Merge v2.0.3 into stable
  • Loading branch information
Carnagion authored Aug 10, 2022
2 parents df24477 + 5aaa750 commit d60c326
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 59 deletions.
2 changes: 1 addition & 1 deletion GDSerializer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<!-- Workaround as Godot does not know how to properly load NuGet packages -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageVersion>2.0.2</PackageVersion>
<PackageVersion>2.0.3</PackageVersion>
<Title>GDSerializer</Title>
<Authors>Carnagion</Authors>
<Description>An XML (de)serialization framework for Godot's C# API.</Description>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ It supports (de)serialization of almost any C# type including collections and ma
**GDSerializer** is available as a [NuGet package](https://www.nuget.org/packages/GDSerializer/), which can be installed either through an IDE or by manually including the following lines in a Godot project's `.csproj` file:
```xml
<ItemGroup>
<PackageReference Include="GDSerializer" Version="2.0.2"/>
<PackageReference Include="GDSerializer" Version="2.0.3"/>
</ItemGroup>
```
Its dependencies may need to be installed as well, in a similar fashion.
Expand Down
68 changes: 37 additions & 31 deletions Serialization/Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ public static bool CanSerialize(PropertyInfo property)
&& property.CanWrite
&& !property.GetIndexParameters().Any()
&& property.GetCustomAttribute<CompilerGeneratedAttribute>() is null
&& property.GetMethod.GetCustomAttribute<CompilerGeneratedAttribute>() is null
&& !Serializer.forbiddenTypes.Contains(property.PropertyType)
&& (property.GetCustomAttribute<SerializeAttribute>()?.Serializable ?? true);
}
Expand Down Expand Up @@ -132,10 +131,9 @@ public XmlNode Serialize(object instance, Type? type = null)
{
type ??= instance.GetType();

XmlNode element;

try
{
XmlNode element;
// Use a more specialized serializer if possible
if (this.TryGetSpecialSerializerForType(type, out ISerializer? serializer))
{
Expand All @@ -144,23 +142,10 @@ public XmlNode Serialize(object instance, Type? type = null)
else
{
XmlDocument context = new();

// Use the "Type" attribute if generic or nested type as ` and + are not allowed as XML node names
if (type.IsGenericType)
{
element = context.CreateElement("Generic");
((XmlElement)element).SetAttribute("Type", type.GetDisplayName().XMLEscape());
}
else if (type.IsNested)
{
element = context.CreateElement("Nested");
((XmlElement)element).SetAttribute("Type", type.GetDisplayName().XMLEscape());
}
else
{
element = context.CreateElement(type.GetDisplayName());
}

element = context.CreateElement("Object");
((XmlElement)element).SetAttribute("Type", type.GetDisplayName());

// Serialize fields and properties
this.SerializeMembers(instance, type).ForEach(pair => element.AppendChild(context.ImportNode(pair.Item1, true)));
}

Expand Down Expand Up @@ -273,11 +258,21 @@ public XmlNode Serialize(object instance, Type? type = null)
{
continue;
}
XmlNode node = context.CreateElement(property.Name);
this.Serialize(value, property.PropertyType).ChildNodes

XmlElement element = context.CreateElement(property.Name);

XmlNode serialized = this.Serialize(value, value.GetType());
string? typeAttribute = serialized.Attributes?["Type"]?.InnerText;
if (typeAttribute is not null)
{
element.SetAttribute("Type", typeAttribute);
}

serialized.ChildNodes
.Cast<XmlNode>()
.ForEach(child => node.AppendChild(context.ImportNode(child, true)));
yield return (node, property);
.ForEach(child => element.AppendChild(context.ImportNode(child, true)));

yield return (element, property);
}

// Recursively serialize fields
Expand All @@ -288,11 +283,21 @@ public XmlNode Serialize(object instance, Type? type = null)
{
continue;
}
XmlNode node= context.CreateElement(field.Name);
this.Serialize(value, field.FieldType).ChildNodes

XmlElement element = context.CreateElement(field.Name);

XmlNode serialized = this.Serialize(value, value.GetType());
string? typeAttribute = serialized.Attributes?["Type"]?.InnerText;
if (typeAttribute is not null)
{
element.SetAttribute("Type", typeAttribute);
}

serialized.ChildNodes
.Cast<XmlNode>()
.ForEach(child => node.AppendChild(context.ImportNode(child, true)));
yield return (node, field);
.ForEach(child => element.AppendChild(context.ImportNode(child, true)));

yield return (element, field);
}
}

Expand Down Expand Up @@ -320,7 +325,7 @@ public XmlNode Serialize(object instance, Type? type = null)
{
throw new SerializationException(child, $"Attempted to deserialize non-deserializable property {property.Name} in {type.GetDisplayName()}");
}
deserialized.Add((this.Deserialize(child, property.PropertyType), property));
deserialized.Add((this.Deserialize(child, child.GetTypeToDeserialize() ?? property.PropertyType), property));
continue;
}

Expand All @@ -332,7 +337,7 @@ public XmlNode Serialize(object instance, Type? type = null)
{
throw new SerializationException(child, $"Attempted to deserialize non-deserializable field {field.Name} in {type.GetDisplayName()}");
}
deserialized.Add((this.Deserialize(child, field.FieldType), field));
deserialized.Add((this.Deserialize(child, child.GetTypeToDeserialize() ?? field.FieldType), field));
continue;
}

Expand All @@ -345,7 +350,8 @@ public XmlNode Serialize(object instance, Type? type = null)
.Where(pair => pair.Item2 is not null && pair.Item2.Serializable)
.Select(pair => pair.member)
.ToArray();
if (toDeserialize.Any() && !toDeserialize.All(deserialized.Select(pair => pair.Item2).Contains))
HashSet<MemberInfo> deserializedMembers = deserialized.Select(pair => pair.Item2).ToHashSet();
if (toDeserialize.Any() && !toDeserialize.All(deserializedMembers.Contains))
{
throw new SerializationException(node, $"One or more mandatory properties or fields of {type.GetDisplayName()} were not deserialized");
}
Expand Down
2 changes: 1 addition & 1 deletion Serialization/Specialized/ArraySerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public override XmlNode Serialize(object instance, Type? arrayType = null)

XmlDocument context = new();
XmlElement arrayElement = context.CreateElement("Array");
arrayElement.SetAttribute("Type", $"{itemType.GetDisplayName().XMLEscape()}[]");
arrayElement.SetAttribute("Type", $"{itemType.GetDisplayName()}[]");
this.SerializeItems(instance, itemType).ForEach(node => arrayElement.AppendChild(context.ImportNode(node, true)));
return arrayElement;
}
Expand Down
4 changes: 2 additions & 2 deletions Serialization/Specialized/CollectionSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public virtual XmlNode Serialize(object instance, Type? collectionType = null)

XmlDocument context = new();
XmlElement collectionElement = context.CreateElement("Collection");
collectionElement.SetAttribute("Type", collectionType.GetDisplayName().XMLEscape());
collectionElement.SetAttribute("Type", collectionType.GetDisplayName());
this.SerializeItems(instance, itemType).ForEach(node => collectionElement.AppendChild(context.ImportNode(node, true)));
return collectionElement;
}
Expand Down Expand Up @@ -97,7 +97,7 @@ protected IEnumerable<XmlNode> SerializeItems(object instance, Type itemType)
XmlElement itemElement = context.CreateElement("item");
if (item.GetType() != itemType)
{
itemElement.SetAttribute("Type", item.GetType().GetDisplayName().XMLEscape());
itemElement.SetAttribute("Type", item.GetType().GetDisplayName());
}
this.ItemSerializer.Serialize(item, item.GetType()).ChildNodes
.Cast<XmlNode>()
Expand Down
6 changes: 3 additions & 3 deletions Serialization/Specialized/DictionarySerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public XmlNode Serialize(object instance, Type? dictionaryType = null)

XmlDocument context = new();
XmlElement dictionaryElement = context.CreateElement("Dictionary");
dictionaryElement.SetAttribute("Type", dictionaryType.GetDisplayName().XMLEscape());
dictionaryElement.SetAttribute("Type", dictionaryType.GetDisplayName());

foreach (object item in (IEnumerable)instance)
{
Expand All @@ -60,7 +60,7 @@ public XmlNode Serialize(object instance, Type? dictionaryType = null)
XmlElement keyElement = context.CreateElement("key");
if (key.GetType() != keyType)
{
keyElement.SetAttribute("Type", key.GetType().GetDisplayName().XMLEscape());
keyElement.SetAttribute("Type", key.GetType().GetDisplayName());
}
this.itemSerializer.Serialize(key, key.GetType()).ChildNodes
.Cast<XmlNode>()
Expand All @@ -69,7 +69,7 @@ public XmlNode Serialize(object instance, Type? dictionaryType = null)
XmlElement valueElement = context.CreateElement("value");
if (value.GetType() != valueType)
{
valueElement.SetAttribute("Type", value.GetType().GetDisplayName().XMLEscape());
valueElement.SetAttribute("Type", value.GetType().GetDisplayName());
}
this.itemSerializer.Serialize(value, value.GetType()).ChildNodes
.Cast<XmlNode>()
Expand Down
2 changes: 1 addition & 1 deletion Serialization/Specialized/EnumerableSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public override XmlNode Serialize(object instance, Type? enumerableType = null)

XmlDocument context = new();
XmlElement enumerableElement = context.CreateElement("Enumerable");
enumerableElement.SetAttribute("Type", enumerableType.GetDisplayName().XMLEscape());
enumerableElement.SetAttribute("Type", enumerableType.GetDisplayName());
this.SerializeItems(instance, itemType).ForEach(node => enumerableElement.AppendChild(context.ImportNode(node, true)));
return enumerableElement;
}
Expand Down
23 changes: 4 additions & 19 deletions Serialization/Specialized/NodeSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,10 @@ public override XmlNode Serialize(object instance, Type? nodeType = null)

XmlDocument context = new();

// Use the "Type" attribute if generic or nested type as ` and + are not allowed as XML node names
XmlElement element;
if (nodeType.IsGenericType)
{
element = context.CreateElement("Generic");
element.SetAttribute("Type", nodeType.GetDisplayName().XMLEscape());
}
else if (nodeType.IsNested)
{
element = context.CreateElement("Nested");
element.SetAttribute("Type", nodeType.GetDisplayName().XMLEscape());
}
else
{
element = context.CreateElement(nodeType.GetDisplayName());
}

Serializer defaultSerializer = (Serializer)this.ItemSerializer;
XmlElement element = context.CreateElement("Node");
element.SetAttribute("Type", nodeType.GetDisplayName());

Serializer defaultSerializer = (Serializer)this.ItemSerializer;
defaultSerializer.SerializeMembers(nodeInstance, nodeType).ForEach(pair => element.AppendChild(context.ImportNode(pair.Item1, true)));

if (nodeInstance.GetChildCount() is 0)
Expand Down Expand Up @@ -90,7 +75,7 @@ public override object Deserialize(XmlNode node, Type? nodeType = null)
{
node.RemoveChild(childrenElement);
}

Serializer defaultSerializer = (Serializer)this.ItemSerializer;

object instance = Activator.CreateInstance(nodeType, true) ?? throw new SerializationException(node, $"Unable to instantiate {nodeType.GetDisplayName()}");
Expand Down

0 comments on commit d60c326

Please sign in to comment.