diff --git a/src/Cid.cs b/src/Cid.cs index 074640a..60c3779 100644 --- a/src/Cid.cs +++ b/src/Cid.cs @@ -1,7 +1,9 @@ using Google.Protobuf; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; +using System.Runtime.Serialization; using System.Text; namespace Ipfs @@ -22,6 +24,7 @@ namespace Ipfs /// /// /// + [JsonConverter(typeof(Cid.Json))] public class Cid : IEquatable { /// @@ -482,5 +485,33 @@ static public implicit operator string(Cid id) { return id.Encode(); } + + /// + /// Conversion of a to and from JSON. + /// + /// + /// The JSON is just a single string value. + /// + class Json : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return true; + } + public override bool CanRead => true; + public override bool CanWrite => true; + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var cid = value as Cid; + writer.WriteValue(cid?.Encode()); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var s = reader.Value as string; + return s == null ? null : Cid.Decode(s); + } + } + } } diff --git a/src/MultiAddress.cs b/src/MultiAddress.cs index bce04d9..e640990 100644 --- a/src/MultiAddress.cs +++ b/src/MultiAddress.cs @@ -5,6 +5,7 @@ using System.IO; using Common.Logging; using Google.Protobuf; +using Newtonsoft.Json; namespace Ipfs { @@ -25,6 +26,7 @@ namespace Ipfs /// /// /// + [JsonConverter(typeof(MultiAddress.Json))] public class MultiAddress : IEquatable { /// @@ -379,6 +381,34 @@ public static MultiAddress TryCreate(string s) } } + /// + /// Conversion of a to and from JSON. + /// + /// + /// The JSON is just a single string value. + /// + class Json : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return true; + } + public override bool CanRead => true; + public override bool CanWrite => true; + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var ma = value as MultiAddress; + writer.WriteValue(ma?.ToString()); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var s = reader.Value as string; + return s == null ? null : new MultiAddress(s); + } + } + + } } \ No newline at end of file diff --git a/src/MultiHash.cs b/src/MultiHash.cs index 0cf726a..7cb30fc 100644 --- a/src/MultiHash.cs +++ b/src/MultiHash.cs @@ -7,6 +7,7 @@ using Common.Logging; using Google.Protobuf; using Ipfs.Registry; +using Newtonsoft.Json; namespace Ipfs { @@ -18,6 +19,7 @@ namespace Ipfs /// See the registry for supported algorithms. /// /// + [JsonConverter(typeof(MultiHash.Json))] public class MultiHash : IEquatable { static readonly ILog log = LogManager.GetLogger(); @@ -497,6 +499,32 @@ public static MultiHash ComputeHash(Stream data, string algorithmName = DefaultA return new MultiHash(algorithmName, GetHashAlgorithm(algorithmName).ComputeHash(data)); } + /// + /// Conversion of a to and from JSON. + /// + /// + /// The JSON is just a single string value. + /// + class Json : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return true; + } + public override bool CanRead => true; + public override bool CanWrite => true; + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var mh = value as MultiHash; + writer.WriteValue(mh?.ToString()); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var s = reader.Value as string; + return s == null ? null : new MultiHash(s); + } + } } /// @@ -510,4 +538,5 @@ public class UnknownHashingAlgorithmEventArgs : EventArgs /// public HashingAlgorithm Algorithm { get; set; } } + } \ No newline at end of file diff --git a/test/CidTest.cs b/test/CidTest.cs index f571bce..eac8c41 100644 --- a/test/CidTest.cs +++ b/test/CidTest.cs @@ -5,6 +5,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using System.IO; using Google.Protobuf; +using Newtonsoft.Json; namespace Ipfs { @@ -359,5 +360,38 @@ public void Immutable() ExceptionAssert.Throws(() => cid.Hash = "QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L5"); ExceptionAssert.Throws(() => cid.Version = 0); } + + class CidAndX + { + public Cid Cid; + public int X; + } + + [TestMethod] + public void JsonSerialization() + { + Cid a = "QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L4"; + string json = JsonConvert.SerializeObject(a); + Assert.AreEqual($"\"{a.Encode()}\"", json); + var b = JsonConvert.DeserializeObject(json); + Assert.AreEqual(a, b); + + a = null; + json = JsonConvert.SerializeObject(a); + b = JsonConvert.DeserializeObject(json); + Assert.IsNull(b); + + var x = new CidAndX { Cid = "QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L4", X = 42 }; + json = JsonConvert.SerializeObject(x); + var y = JsonConvert.DeserializeObject(json); + Assert.AreEqual(x.Cid, y.Cid); + Assert.AreEqual(x.X, y.X); + + x.Cid = null; + json = JsonConvert.SerializeObject(x); + y = JsonConvert.DeserializeObject(json); + Assert.AreEqual(x.Cid, y.Cid); + Assert.AreEqual(x.X, y.X); + } } } diff --git a/test/MultiAddressTest.cs b/test/MultiAddressTest.cs index 218dea0..d249681 100644 --- a/test/MultiAddressTest.cs +++ b/test/MultiAddressTest.cs @@ -4,6 +4,7 @@ using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.IO; +using Newtonsoft.Json; namespace Ipfs { @@ -307,6 +308,22 @@ public void TryCreate() Assert.IsNull(MultiAddress.TryCreate("/tcp/alpha")); // bad port Assert.IsNull(MultiAddress.TryCreate("/foobar")); // bad protocol } + + [TestMethod] + public void JsonSerialization() + { + var a = new MultiAddress("/ip6/fe80::7573:b0a8:46b0:0bad/tcp/4009"); + string json = JsonConvert.SerializeObject(a); + Assert.AreEqual($"\"{a.ToString()}\"", json); + var b = JsonConvert.DeserializeObject(json); + Assert.AreEqual(a.ToString(), b.ToString()); + + a = null; + json = JsonConvert.SerializeObject(a); + b = JsonConvert.DeserializeObject(json); + Assert.IsNull(b); + } + } } diff --git a/test/MultiHashTest.cs b/test/MultiHashTest.cs index 0d90f0f..320dcb8 100644 --- a/test/MultiHashTest.cs +++ b/test/MultiHashTest.cs @@ -6,6 +6,7 @@ using System.Text; using System.IO; using Google.Protobuf; +using Newtonsoft.Json; namespace Ipfs { @@ -469,5 +470,20 @@ public void Binary() CollectionAssert.AreEqual(mh.Digest, mh1.Digest); } + [TestMethod] + public void JsonSerialization() + { + var a = new MultiHash("QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB"); + string json = JsonConvert.SerializeObject(a); + Assert.AreEqual($"\"{a.ToString()}\"", json); + var b = JsonConvert.DeserializeObject(json); + Assert.AreEqual(a, b); + + a = null; + json = JsonConvert.SerializeObject(a); + b = JsonConvert.DeserializeObject(json); + Assert.IsNull(b); + } + } }