Last active
September 6, 2024 14:45
-
-
Save deanebarker/d9983155603d1adf26197787a9c74ae4 to your computer and use it in GitHub Desktop.
A combined search and deserialization library using JSONata syntax
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Requires Nuget package Jsonata.Net.Native | |
// Doc here: https://deanebarker.net/tech/code/jsonata-doc/ | |
public class JsonataDoc | |
{ | |
// This is public so you can change the options if you want | |
public JsonSerializerOptions DeserializerOptions = new(); | |
private string json; | |
public JsonataDoc(string input) | |
{ | |
json = input; | |
DeserializerOptions.Converters.Add(new NullableDateTimeConverter()); | |
DeserializerOptions.Converters.Add(new SafeStringTimeConverter()); | |
DeserializerOptions.PropertyNameCaseInsensitive = true; | |
} | |
public string GetString(string query) | |
{ | |
return GetObject<string>(query); | |
} | |
public double GetNumber(string query) | |
{ | |
return GetObject<double>(query); | |
} | |
public DateTime? GetDate(string query) | |
{ | |
return GetObject<DateTime?>(query); | |
} | |
public List<T> GetList<T>(string query) | |
{ | |
return GetObject<List<T>>(query); | |
} | |
public List<Dictionary<string, string>> GetDictionaries(string query) | |
{ | |
var result = GetResult(query); | |
var doc = JsonDocument.Parse(result); | |
var list = new List<Dictionary<string, string>>(); | |
foreach (var item in doc.RootElement.EnumerateArray()) | |
{ | |
var thisItem = new Dictionary<string, string>(); | |
foreach (var prop in item.EnumerateObject()) | |
{ | |
thisItem[prop.Name] = prop.Value.GetString(); | |
} | |
list.Add(thisItem); | |
} | |
return list; | |
} | |
public string GetResult(string query) | |
{ | |
var q = new JsonataQuery(query); | |
return q.Eval(json); | |
} | |
public T GetObject<T>(string query) | |
{ | |
var result = GetResult(query); | |
return (T)DeserializeTo<T>(result); | |
} | |
private T DeserializeTo<T>(string json) | |
{ | |
return (T)JsonSerializer.Deserialize(json, typeof(T), DeserializerOptions); | |
} | |
// This is so we don't break if a date string can't be parsed... | |
internal class NullableDateTimeConverter : JsonConverter<DateTime?> | |
{ | |
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
{ | |
if (DateTime.TryParse(reader.GetString(), out DateTime result)) | |
{ | |
return result; | |
} | |
return null; | |
} | |
public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options) | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
// This is because the default JSON deserializer is too stupid to turn a number into a string... | |
internal class SafeStringTimeConverter : JsonConverter<string> | |
{ | |
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
{ | |
if (reader.TokenType == JsonTokenType.Number) | |
{ | |
var value = reader.GetInt64(); | |
return value.ToString(); | |
} | |
return reader.GetString(); | |
} | |
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment