Skip to content

Commit

Permalink
resolve DMD 2.102 deprecations by replacing use of getSymbolsByUDA, g…
Browse files Browse the repository at this point in the history
…etUDAs and hasUDA
  • Loading branch information
Herringway committed Feb 4, 2023
1 parent 40a8232 commit 72f38f7
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 22 deletions.
68 changes: 55 additions & 13 deletions source/siryul/common.d
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module siryul.common;
import std.meta : templateAnd, templateNot, templateOr;
import std.meta : Filter, templateAnd, templateNot, templateOr;
import std.range : isInputRange, isOutputRange;
import std.traits : arity, getSymbolsByUDA, getUDAs, hasUDA, isArray, isAssociativeArray, isInstanceOf, isIterable, isSomeString, TemplateArgsOf, TemplateOf;
import std.typecons : BitFlags, Nullable, NullableRef;
Expand Down Expand Up @@ -79,15 +79,17 @@ struct SiryulizeAs {
///Serialized field name
string name;
}
private struct Optional_ {}
private struct Required_ {}
/++
+ Used when nonpresence of field is not an error. The field will be set to its
+ .init value. If being able to detect nonpresence is desired, ensure that
+ the default value cannot appear in the data or use a Nullable type.
+/
enum Optional;
enum Optional = Optional_.init;

///Used when nonpresence of field is an error.
enum Required;
enum Required = Required_.init;

/++
+ Use custom parser functions for a given field.
Expand All @@ -103,19 +105,45 @@ struct CustomParser {
///Function to be used in serialization
string toFunc;
}
private struct AsString_ {}
private struct AsBinary_ {}
private struct SerializationMethod_ {}
private struct DeserializationMethod_ {}
///Write field as string
enum AsString;
enum AsString = AsString_.init;
///Write field as binary (NYI)
enum AsBinary;
enum AsBinary = AsBinary_.init;
///Marks a method for use in serialization
enum SerializationMethod;
enum SerializationMethod = SerializationMethod_.init;
///Marks a method for use in deserialization
enum DeserializationMethod;

enum hasSerializationMethod(T) = getSymbolsByUDA!(T, SerializationMethod).length == 1;
alias serializationMethod(T) = getSymbolsByUDA!(T, SerializationMethod)[0];
enum hasDeserializationMethod(T) = getSymbolsByUDA!(T, DeserializationMethod).length == 1;
alias deserializationMethod(T) = getSymbolsByUDA!(T, DeserializationMethod)[0];
enum DeserializationMethod= DeserializationMethod_.init;

enum hasSerializationMethod(alias T) = is(typeof(serializationMethod!T));
template serializationMethod(alias T) {
static foreach (m; __traits(allMembers, T)) {
static foreach (overload; __traits(getOverloads, T, m)) {
static if (!is(typeof(serializationMethod_)) && isSerializationMethod!overload) {
alias serializationMethod_ = overload;
} else static if (isSerializationMethod!overload) {
static assert(!is(typeof(serializationMethod_)), "Only one serialization method may be specified");
}
}
}
alias serializationMethod = serializationMethod_;
}
template deserializationMethod(alias T) {
static foreach (m; __traits(allMembers, T)) {
static foreach (overload; __traits(getOverloads, T, m)) {
static if (!is(typeof(deserializationMethod_)) && isDeserializationMethod!overload) {
alias deserializationMethod_ = overload;
} else static if (isDeserializationMethod!overload) {
static assert(!is(typeof(deserializationMethod_)), "Only one deserialization method may be specified");
}
}
}
alias deserializationMethod = deserializationMethod_;
}
enum hasDeserializationMethod(alias T) = is(typeof(deserializationMethod!T));

enum hasSerializationTemplate(T) = is(typeof(T.toSiryulType));
alias serializationTemplate(T) = T.toSiryulType;
Expand All @@ -135,7 +163,7 @@ package template getMemberName(alias T) {
static if (hasUDA!(T, SiryulizeAs)) {
enum getMemberName = getUDAs!(T, SiryulizeAs)[0].name;
} else
enum getMemberName = T.stringof;
enum getMemberName = __traits(identifier, T);
}
unittest {
struct TestStruct {
Expand Down Expand Up @@ -502,3 +530,17 @@ Duration fromISODurationString(string str) @safe pure {
assert("P1W1D".fromISODurationString == 1.weeks + 1.days);
assert("P1W1DT0.5S".fromISODurationString == 1.weeks + 1.days + 500.msecs);
}

private template typeMatches(T) {
enum typeMatches(alias t) = is(typeof(t) == T);
}

enum isSerializationMethod(alias sym) = Filter!(typeMatches!SerializationMethod_, __traits(getAttributes, sym)).length == 1;

enum isDeserializationMethod(alias sym) = Filter!(typeMatches!DeserializationMethod_, __traits(getAttributes, sym)).length == 1;

enum isOptional(alias sym) = Filter!(typeMatches!Optional_, __traits(getAttributes, sym)).length == 1;

enum isRequired(alias sym) = Filter!(typeMatches!Required_, __traits(getAttributes, sym)).length == 1;

enum shouldStringify(alias sym) = Filter!(typeMatches!AsString_, __traits(getAttributes, sym)).length == 1;
10 changes: 5 additions & 5 deletions source/siryul/dyaml.d
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ template deserialize(Serializer : YAML, BitFlags!DeSiryulize flags) {
import std.datetime : Date, DateTime, SysTime, TimeOfDay;
import std.exception : enforce;
import std.range : enumerate, isOutputRange, put;
import std.traits : arity, FieldNameTuple, ForeachType, getUDAs, hasIndirections, hasUDA, isAggregateType, isArray, isAssociativeArray, isFloatingPoint, isIntegral, isPointer, isSomeString, isStaticArray, KeyType, OriginalType, Parameters, PointerTarget, TemplateArgsOf, ValueType;
import std.traits : arity, FieldNameTuple, ForeachType, hasIndirections, isAggregateType, isArray, isAssociativeArray, isFloatingPoint, isIntegral, isPointer, isSomeString, isStaticArray, KeyType, OriginalType, Parameters, PointerTarget, TemplateArgsOf, ValueType;
import std.utf : byCodeUnit;
void deserialize(T)(Node value, string path, out T result) if (is(T == enum)) {
import std.traits : OriginalType;
Expand Down Expand Up @@ -162,7 +162,7 @@ template deserialize(Serializer : YAML, BitFlags!DeSiryulize flags) {
void deserialize(T)(Node value, string path, out T result) if (is(T == struct) && !isSumType!T && !isNullable!T && !isTimeType!T && !hasDeserializationMethod!T && !hasDeserializationTemplate!T) {
import std.exception : enforce;
import std.meta : AliasSeq;
import std.traits : arity, FieldNameTuple, ForeachType, getUDAs, hasIndirections, hasUDA, isAssociativeArray, isFloatingPoint, isIntegral, isPointer, isSomeChar, isSomeString, isStaticArray, OriginalType, Parameters, PointerTarget, TemplateArgsOf, ValueType;
import std.traits : arity, FieldNameTuple, ForeachType, hasIndirections, isAssociativeArray, isFloatingPoint, isIntegral, isPointer, isSomeChar, isSomeString, isStaticArray, OriginalType, Parameters, PointerTarget, TemplateArgsOf, ValueType;
expect(value, NodeID.mapping);
foreach (member; FieldNameTuple!T) {
static if (__traits(getProtection, __traits(getMember, T, member)) == "public") {
Expand All @@ -171,7 +171,7 @@ template deserialize(Serializer : YAML, BitFlags!DeSiryulize flags) {
alias field = AliasSeq!(__traits(getMember, T, member));
enum memberName = getMemberName!field;
const valueIsAbsent = memberName !in value;
static if ((hasUDA!(field, Optional) || (!!(flags & DeSiryulize.optionalByDefault)) && !hasUDA!(field, Required)) || hasIndirections!(typeof(field))) {
static if ((isOptional!field || (!!(flags & DeSiryulize.optionalByDefault)) && !isRequired!field) || hasIndirections!(typeof(field))) {
if (!hasConvertFromFunc!(T, field) && valueIsAbsent) {
continue;
}
Expand Down Expand Up @@ -253,7 +253,7 @@ template deserialize(Serializer : YAML, BitFlags!DeSiryulize flags) {
template serialize(Serializer : YAML, BitFlags!Siryulize flags) {
import std.conv : text, to;
import std.datetime : Date, DateTime, SysTime, TimeOfDay;
import std.traits : arity, FieldNameTuple, getSymbolsByUDA, getUDAs, hasUDA, isAggregateType, isAssociativeArray, isPointer, isSomeString, isStaticArray, PointerTarget, Unqual;
import std.traits : arity, FieldNameTuple, isAggregateType, isAssociativeArray, isPointer, isSomeString, isStaticArray, PointerTarget, Unqual;
private Node serialize(const typeof(null) value) {
return Node(YAMLNull());
}
Expand All @@ -276,7 +276,7 @@ template serialize(Serializer : YAML, BitFlags!Siryulize flags) {
import std.utf : toUTF8;
return serialize(value[].toUTF8().idup);
}
private Node serialize(T)(auto ref const T value) if (hasUDA!(value, AsString) || is(T == enum)) {
private Node serialize(T)(auto ref const T value) if (shouldStringify!value || is(T == enum)) {
return Node(value.text);
}
private Node serialize(T)(auto ref const T value) if (isAssociativeArray!T) {
Expand Down
8 changes: 4 additions & 4 deletions source/siryul/json.d
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ template deserialize(Serializer : JSON, BitFlags!DeSiryulize flags) {
} else {
import std.exception : enforce;
import std.meta : AliasSeq;
import std.traits : arity, FieldNameTuple, ForeachType, getUDAs, hasIndirections, hasUDA, isAssociativeArray, isFloatingPoint, isIntegral, isPointer, isSomeChar, isSomeString, isStaticArray, OriginalType, Parameters, PointerTarget, TemplateArgsOf, ValueType;
import std.traits : arity, FieldNameTuple, ForeachType, hasIndirections, isAssociativeArray, isFloatingPoint, isIntegral, isPointer, isSomeChar, isSomeString, isStaticArray, OriginalType, Parameters, PointerTarget, TemplateArgsOf, ValueType;
expect(value, JSONType.object);
foreach (member; FieldNameTuple!T) {
static if (__traits(getProtection, __traits(getMember, T, member)) == "public") {
Expand All @@ -116,7 +116,7 @@ template deserialize(Serializer : JSON, BitFlags!DeSiryulize flags) {
alias field = AliasSeq!(__traits(getMember, T, member));
enum memberName = getMemberName!field;
const valueIsAbsent = (memberName !in value.objectNoRef) || (value.objectNoRef[memberName].type == JSONType.null_);
static if ((hasUDA!(field, Optional) || (!!(flags & DeSiryulize.optionalByDefault)) && !hasUDA!(field, Required)) || hasIndirections!(typeof(field))) {
static if ((isOptional!field || (!!(flags & DeSiryulize.optionalByDefault)) && !isRequired!field) || hasIndirections!(typeof(field))) {
if (!hasConvertFromFunc!(T, field) && valueIsAbsent) {
continue;
}
Expand Down Expand Up @@ -222,7 +222,7 @@ template deserialize(Serializer : JSON, BitFlags!DeSiryulize flags) {
}

template serialize(Serializer : JSON, BitFlags!Siryulize flags) {
import std.traits : hasUDA, isAggregateType, Unqual;
import std.traits : isAggregateType, Unqual;
private JSONValue serialize(T)(ref const T value) if (is(T == struct) && !isSumType!T && !isNullable!T && !isTimeType!T && !hasSerializationMethod!T && !hasSerializationTemplate!T) {
import std.traits : FieldNameTuple;
string[string] arr;
Expand Down Expand Up @@ -256,7 +256,7 @@ template serialize(Serializer : JSON, BitFlags!Siryulize flags) {
private JSONValue serialize(const typeof(null) value) {
return JSONValue();
}
private JSONValue serialize(T)(ref const T value) if (hasUDA!(value, AsString) || is(T == enum)) {
private JSONValue serialize(T)(ref const T value) if (shouldStringify!value || is(T == enum)) {
import std.conv : text;
return JSONValue(value.text);
}
Expand Down

0 comments on commit 72f38f7

Please sign in to comment.