Skip to content

Instantly share code, notes, and snippets.

@Thaina
Last active December 27, 2017 08:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Thaina/82071ca2814755ef3571fec352f2e44c to your computer and use it in GitHub Desktop.
Save Thaina/82071ca2814755ef3571fec352f2e44c to your computer and use it in GitHub Desktop.
using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Google.Protobuf;
using Google.Protobuf.Collections;
using Google.Cloud.Firestore.V1Beta1;
public static partial class Ext
{
public static JObject ToJSon<T>(this T fields) where T : IEnumerable<KeyValuePair<string,Value>>
{
return JObject.FromObject(fields.ToDictionary((pair) => pair.Key,(pair) => pair.Value.ToJSon()));
}
public static JToken ToJSon(this Value input)
{
switch(input?.ValueTypeCase)
{
case null:
return null;
case Value.ValueTypeOneofCase.NullValue:
return JValue.CreateNull();
case Value.ValueTypeOneofCase.BooleanValue:
return input.BooleanValue;
case Value.ValueTypeOneofCase.StringValue:
return input.StringValue;
case Value.ValueTypeOneofCase.DoubleValue:
return input.DoubleValue;
case Value.ValueTypeOneofCase.IntegerValue:
return input.IntegerValue;
case Value.ValueTypeOneofCase.ArrayValue:
return new JArray(input.ArrayValue?.Values.Select((item) => item.ToJSon()));
case Value.ValueTypeOneofCase.MapValue:
return JObject.FromObject(input.MapValue.Fields.ToDictionary((pair) => pair.Key,(pair) => pair.Value.ToJSon()));
case Value.ValueTypeOneofCase.BytesValue:
return input.BytesValue.ToByteArray();
case Value.ValueTypeOneofCase.TimestampValue:
return input.TimestampValue.ToDateTimeOffset();
case Value.ValueTypeOneofCase.ReferenceValue:
return new JObject(){ ["referenceValue"] = input.ReferenceValue };
case Value.ValueTypeOneofCase.GeoPointValue:
return new JObject(){ ["geoPointValue"] = JObject.FromObject(input.GeoPointValue) };
default:
throw new NotSupportedException(input.ValueTypeCase.ToString());
}
}
public static MapField<string,Value> ToFields<T>(this JObject fields)
{
var map = new MapField<string,Value>();
map.Add(fields.Properties().ToDictionary((pair) => pair.Name,(pair) => pair.Value.ToValue()));
return map;
}
static readonly string[] FireStoreValueNames = new[]{ "nullValue","booleanValue","integerValue","doubleValue","timestampValue","stringValue","bytesValue","referenceValue","geoPointValue","arrayValue","mapValue"};
public static Value ToValue(this JToken input)
{
if(input is null)
return null;
if(input is JObject jobj)
{
if(jobj.Properties().FirstOrDefault() is JProperty prop && FireStoreValueNames.Contains(prop.Name))
return Value.Parser.ParseJson(prop.Value.ToString());
var map = new MapValue();
map.Fields.Add(jobj.Properties().ToDictionary((pair) => pair.Name,(pair) => pair.Value.ToValue()));
return new Value() { MapValue = map };
}
if(input is JArray jarr)
{
var arr = new ArrayValue();
arr.Values.Add(jarr.Select((item) => item.ToValue()));
return new Value() { ArrayValue = arr };
}
switch(input.Type)
{
case JTokenType.None:
case JTokenType.Null:
return new Value() { NullValue = Google.Protobuf.WellKnownTypes.NullValue.NullValue };
case JTokenType.Boolean:
return new Value() { BooleanValue = (bool)input };
case JTokenType.Integer:
return new Value() { IntegerValue = (long)input };
case JTokenType.Float:
return new Value() { DoubleValue = (double)input };
case JTokenType.String:
return new Value() { StringValue = (string)input };
case JTokenType.Date:
return new Value() { TimestampValue = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTimeOffset((DateTimeOffset)input) };
case JTokenType.Bytes:
return new Value() { BytesValue = ByteString.CopyFrom((byte[])input) };
default:
throw new NotSupportedException(input.ToString(Formatting.None));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment