Skip to content

Commit 14ea5bc

Browse files
Implemented optional extenions instead of confusing default interface methods.
1 parent 2a649ae commit 14ea5bc

11 files changed

+211
-80
lines changed

Open.Serialization/DefaultMethods.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,21 @@ public static async ValueTask SerializeAsync<T>(ISerialize<T> serializer, Stream
9191
await writer.WriteAsync(text).ConfigureAwait(false);
9292
}
9393

94+
/// <summary>
95+
/// Creates a type specific serializer using this as the underlying serializer.
96+
/// </summary>
97+
/// <returns>A type specific serializer.</returns>
98+
public static Serializer<T> Cast<T>(this ISerializer serializer)
99+
{
100+
if (serializer is null)
101+
throw new ArgumentNullException(nameof(serializer));
102+
103+
return serializer is IAsyncSerializer a
104+
? new Serializer<T>(
105+
serializer.Deserialize<T>, serializer.Serialize<T>,
106+
a.DeserializeAsync<T>, a.SerializeAsync<T>)
107+
: new Serializer<T>(
108+
serializer.Deserialize<T>, serializer.Serialize<T>);
109+
}
94110
}
95111
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
using System;
2+
using System.IO;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
6+
namespace Open.Serialization.Extensions
7+
{
8+
/// <summary>
9+
/// Default extensions for pure serialization interfaces.
10+
/// </summary>
11+
public static class SerializationExtensions
12+
{
13+
/// <inheritdoc cref="IDeserialize.Deserialize{T}(string)" />
14+
public static T Deserialize<T>(this IDeserializeObject deserializer, string? value)
15+
{
16+
if (deserializer is null) throw new ArgumentNullException(nameof(deserializer));
17+
return deserializer is IDeserialize d
18+
? d.Deserialize<T>(value)
19+
: (T)deserializer.Deserialize(value, typeof(T))!;
20+
}
21+
22+
/// <inheritdoc cref="ISerialize.Serialize{T}(T)" />
23+
public static string? Serialize<T>(this ISerializeObject serializer, T item)
24+
{
25+
if (serializer is null) throw new ArgumentNullException(nameof(serializer));
26+
return serializer is ISerialize s
27+
? s.Serialize(item)
28+
: serializer.Serialize(item, typeof(T));
29+
}
30+
31+
/// <inheritdoc cref="IDeserializeAsync.DeserializeAsync{T}(Stream, CancellationToken)" />
32+
public static async ValueTask<T> DeserializeAsync<T>(this IDeserializeObject deserializer, Stream source, CancellationToken cancellationToken = default)
33+
{
34+
if (deserializer is null) throw new ArgumentNullException(nameof(deserializer));
35+
return deserializer is IDeserializeAsync d
36+
? await d.DeserializeAsync<T>(source, cancellationToken)
37+
: (T)(await DeserializeAsync(deserializer, source, typeof(T), cancellationToken))!;
38+
}
39+
40+
/// <inheritdoc cref="IDeserializeObjectAsync.DeserializeAsync(Stream, Type, CancellationToken)" />
41+
public static ValueTask<object?> DeserializeAsync(this IDeserializeObject deserializer, Stream source, Type type, CancellationToken cancellationToken = default)
42+
{
43+
if (deserializer is null) throw new ArgumentNullException(nameof(deserializer));
44+
return deserializer is IDeserializeObjectAsync d
45+
? d.DeserializeAsync(source, type, cancellationToken)
46+
: DefaultMethods.DeserializeAsync(deserializer, source, type);
47+
}
48+
49+
/// <inheritdoc cref="IDeserializeAsync.DeserializeAsync{T}(Stream, CancellationToken)" />
50+
public static async ValueTask<T> DeserializeAsync<T>(this IDeserializeObjectAsync deserializer, Stream source, CancellationToken cancellationToken = default)
51+
{
52+
if (deserializer is null) throw new ArgumentNullException(nameof(deserializer));
53+
return deserializer is IDeserializeAsync d
54+
? await d.DeserializeAsync<T>(source, cancellationToken)
55+
: (T)(await deserializer.DeserializeAsync(source, typeof(T), cancellationToken))!;
56+
}
57+
58+
/// <inheritdoc cref="ISerializeAsync.SerializeAsync{T}(Stream, T, CancellationToken)"/>
59+
public static ValueTask SerializeAsync<T>(this ISerialize serializer, Stream target, T item, CancellationToken cancellationToken = default)
60+
{
61+
if (serializer is null) throw new ArgumentNullException(nameof(serializer));
62+
return serializer is ISerializeAsync s
63+
? s.SerializeAsync(target, item, cancellationToken)
64+
: DefaultMethods.SerializeAsync(serializer, target, item);
65+
}
66+
67+
/// <inheritdoc cref="ISerializeObjectAsync.SerializeAsync(Stream, object, Type, CancellationToken)"/>
68+
public static ValueTask SerializeAsync(this ISerializeObject serializer, Stream target, object? item, Type type, CancellationToken cancellationToken = default)
69+
{
70+
if (serializer is null) throw new ArgumentNullException(nameof(serializer));
71+
return serializer is ISerializeObjectAsync s
72+
? s.SerializeAsync(target, item, type, cancellationToken)
73+
: DefaultMethods.SerializeAsync(serializer, target, item, type);
74+
}
75+
76+
/// <inheritdoc cref="ISerializeAsync.SerializeAsync{T}(Stream, T, CancellationToken)" />
77+
public static ValueTask SerializeAsync<T>(this ISerializeObject serializer, Stream target, T item, CancellationToken cancellationToken = default)
78+
{
79+
if (serializer is null) throw new ArgumentNullException(nameof(serializer));
80+
return serializer is ISerializeAsync s
81+
? s.SerializeAsync(target, item, cancellationToken)
82+
: SerializeAsync(serializer, target, item, typeof(T), cancellationToken);
83+
}
84+
85+
/// <inheritdoc cref="IDeserializeAsync.DeserializeAsync{T}(Stream, CancellationToken)"/>
86+
public static ValueTask<T> DeserializeAsync<T>(this IDeserialize deserializer, Stream source, CancellationToken cancellationToken = default)
87+
{
88+
if (deserializer is null) throw new ArgumentNullException(nameof(deserializer));
89+
return deserializer is IDeserializeAsync d
90+
? d.DeserializeAsync<T>(source, cancellationToken)
91+
: DefaultMethods.DeserializeAsync<T>(deserializer, source);
92+
}
93+
94+
/// <inheritdoc cref="IDeserializeAsync{T}.DeserializeAsync(Stream, CancellationToken)"/>
95+
public static ValueTask<T> DeserializeAsync<T>(this IDeserialize<T> deserializer, Stream source, CancellationToken cancellationToken = default)
96+
{
97+
if (deserializer is null) throw new ArgumentNullException(nameof(deserializer));
98+
return deserializer is IDeserializeAsync<T> d
99+
? d.DeserializeAsync(source, cancellationToken)
100+
: DefaultMethods.DeserializeAsync(deserializer, source);
101+
}
102+
103+
/// <inheritdoc cref="ISerializeAsync{T}.SerializeAsync(Stream, T, CancellationToken)"/>
104+
public static ValueTask SerializeAsync<T>(this ISerialize<T> serializer, Stream target, T item, CancellationToken cancellationToken = default)
105+
{
106+
if (serializer is null) throw new ArgumentNullException(nameof(serializer));
107+
return serializer is ISerializeAsync s
108+
? s.SerializeAsync(target, item, cancellationToken)
109+
: DefaultMethods.SerializeAsync(serializer, target, item);
110+
}
111+
112+
/// <inheritdoc cref="ISerializeAsync.SerializeAsync{T}(Stream, T, CancellationToken)" />
113+
public static ValueTask SerializeAsync<T>(this ISerializeObjectAsync serializer, Stream target, T item, CancellationToken cancellationToken)
114+
{
115+
if (serializer is null) throw new ArgumentNullException(nameof(serializer));
116+
return serializer is ISerializeAsync s
117+
? s.SerializeAsync(target, item, cancellationToken)
118+
: serializer.SerializeAsync(target, item, typeof(T), cancellationToken);
119+
}
120+
121+
122+
/// <summary>
123+
/// Creates a type specific serializer using this as the underlying serializer.
124+
/// </summary>
125+
/// <returns>A type specific serializer.</returns>
126+
public static Serializer<T> Cast<T>(this ISerializer serializer)
127+
{
128+
if (serializer is null)
129+
throw new ArgumentNullException(nameof(serializer));
130+
131+
return serializer is IAsyncSerializer a
132+
? new Serializer<T>(
133+
serializer.Deserialize<T>, serializer.Serialize<T>,
134+
a.DeserializeAsync<T>, a.SerializeAsync<T>)
135+
: new Serializer<T>(
136+
serializer.Deserialize<T>, serializer.Serialize<T>);
137+
}
138+
}
139+
}

Open.Serialization/IDeserialize.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System.IO;
2-
using System.Threading;
3-
using System.Threading.Tasks;
4-
5-
namespace Open.Serialization
1+
namespace Open.Serialization
62
{
73
/// <summary>
84
/// Interface for deserializing any given generic type.
@@ -15,11 +11,6 @@ public interface IDeserialize
1511
/// <param name="value">The string to deserialize.</param>
1612
/// <returns>The deserialized result.</returns>
1713
T Deserialize<T>(string? value);
18-
19-
#if NETSTANDARD2_1
20-
ValueTask<T> DeserializeAsync<T>(Stream source, CancellationToken cancellationToken = default)
21-
=> DefaultMethods.DeserializeAsync<T>(this, source);
22-
#endif
2314
}
2415

2516
/// <summary>
Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
using System;
2-
using System.IO;
3-
using System.Threading;
4-
using System.Threading.Tasks;
52

63
namespace Open.Serialization
74
{
@@ -17,19 +14,5 @@ public interface IDeserializeObject
1714
/// <param name="type">The expected type.</param>
1815
/// <returns>The deserialized result.</returns>
1916
object? Deserialize(string? value, Type type);
20-
21-
#if NETSTANDARD2_1
22-
/// <inheritdoc cref="IDeserialize.Deserialize{T}(string)" />
23-
T Deserialize<T>(string? value)
24-
=> (T)Deserialize(value, typeof(T))!;
25-
26-
/// <inheritdoc cref="IDeserializeObjectAsync.DeserializeAsync(Stream, Type, CancellationToken)" />
27-
ValueTask<object?> DeserializeAsync(Stream source, Type type, CancellationToken cancellationToken = default)
28-
=> DefaultMethods.DeserializeAsync(this, source, type);
29-
30-
/// <inheritdoc cref="IDeserializeAsync.DeserializeAsync{T}(Stream, CancellationToken)" />
31-
async ValueTask<T> DeserializeAsync<T>(Stream source, CancellationToken cancellationToken)
32-
=> (T)(await DeserializeAsync(source, typeof(T), cancellationToken))!;
33-
#endif
3417
}
3518
}

Open.Serialization/IDeserializeObjectAsync.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,5 @@ public interface IDeserializeObjectAsync
1818
/// <param name="cancellationToken">An optional cancellation token.</param>
1919
/// <returns>The deserialized result.</returns>
2020
ValueTask<object?> DeserializeAsync(Stream source, Type type, CancellationToken cancellationToken = default);
21-
22-
#if NETSTANDARD2_1
23-
/// <inheritdoc cref="IDeserializeAsync.DeserializeAsync{T}(Stream, CancellationToken)" />
24-
async ValueTask<T> DeserializeAsync<T>(Stream source, CancellationToken cancellationToken)
25-
=> (T)(await DeserializeAsync(source, typeof(T), cancellationToken))!;
26-
#endif
2721
}
2822
}

Open.Serialization/ISerialize.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System.IO;
2-
using System.Threading;
3-
using System.Threading.Tasks;
4-
5-
namespace Open.Serialization
1+
namespace Open.Serialization
62
{
73
/// <summary>
84
/// Interface for serializing a given generic type.
@@ -15,11 +11,6 @@ public interface ISerialize
1511
/// <param name="item">The item to deserialze.</param>
1612
/// <returns>The serialized string.</returns>
1713
string? Serialize<T>(T item);
18-
19-
#if NETSTANDARD2_1
20-
ValueTask SerializeAsync<T>(Stream target, T item, CancellationToken cancellationToken = default)
21-
=> DefaultMethods.SerializeAsync<T>(this, target, item);
22-
#endif
2314
}
2415

2516

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
using System;
2-
using System.IO;
3-
using System.Threading;
4-
using System.Threading.Tasks;
52

63
namespace Open.Serialization
74
{
@@ -17,19 +14,5 @@ public interface ISerializeObject
1714
/// <param name="type">The expected type.</param>
1815
/// <returns>The serialized string.</returns>
1916
string? Serialize(object? item, Type type);
20-
21-
#if NETSTANDARD2_1
22-
/// <inheritdoc cref="ISerialize" />
23-
string? Serialize<T>(T item)
24-
=> Serialize(item, typeof(T));
25-
26-
/// <inheritdoc cref="ISerializeObjectAsync.SerializeAsync(Stream, object, Type, CancellationToken)"/>
27-
ValueTask SerializeAsync(Stream target, object? item, Type type, CancellationToken cancellationToken = default)
28-
=> DefaultMethods.SerializeAsync(this, target, item, type);
29-
30-
/// <inheritdoc cref="ISerializeAsync.SerializeAsync{T}(Stream, T, CancellationToken)" />
31-
virtual ValueTask SerializeAsync<T>(Stream target, T item, CancellationToken cancellationToken)
32-
=> SerializeAsync(target, item, typeof(T), cancellationToken);
33-
#endif
3417
}
3518
}

Open.Serialization/ISerializeObjectAsync.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,5 @@ public interface ISerializeObjectAsync
1818
/// <param name="type">The expected type.</param>
1919
/// <param name="cancellationToken">An optional cancellation token.</param>
2020
ValueTask SerializeAsync(Stream target, object? item, Type type, CancellationToken cancellationToken = default);
21-
22-
#if NETSTANDARD2_1
23-
/// <inheritdoc cref="ISerializeAsync.SerializeAsync{T}(Stream, T, CancellationToken)" />
24-
virtual ValueTask SerializeAsync<T>(Stream target, T item, CancellationToken cancellationToken)
25-
=> SerializeAsync(target, item, typeof(T), cancellationToken);
26-
#endif
2721
}
2822
}

Open.Serialization/Open.Serialization.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Part of the "Open" set of libraries.
1717
<RepositoryUrl>https://github.com/electricessence/Open.Serialization</RepositoryUrl>
1818
<RepositoryType>git</RepositoryType>
1919
<PackageTags>serialization</PackageTags>
20-
<Version>2.1.0</Version>
20+
<Version>2.2.0</Version>
2121
<Nullable>enable</Nullable>
2222
<PackageReleaseNotes></PackageReleaseNotes>
2323
</PropertyGroup>

Open.Serialization/Open.Serialization.xml

Lines changed: 53 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)