Skip to content

Commit

Permalink
feat(mapbox): updating the converters to work as expected and fixing …
Browse files Browse the repository at this point in the history
…the tests
  • Loading branch information
JustinCanton committed Jan 21, 2024
1 parent ef53190 commit 4ed16e9
Show file tree
Hide file tree
Showing 14 changed files with 266 additions and 160 deletions.
22 changes: 11 additions & 11 deletions src/Geo.ArcGIS/Converters/AttributeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public class AttributeConverter : JsonConverter<Models.Responses.Attribute>
{
private const string LocationAttribute = "LongLabel";
private const string AddressAttribute = "Match_addr";
private static readonly Type Location = typeof(LocationAttribute);
private static readonly Type Address = typeof(AddressAttribute);
private static readonly Type Place = typeof(PlaceAttribute);
private static readonly Type LocationType = typeof(LocationAttribute);
private static readonly Type AddressType = typeof(AddressAttribute);
private static readonly Type PlaceType = typeof(PlaceAttribute);

/// <inheritdoc/>
public override Models.Responses.Attribute Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
Expand Down Expand Up @@ -82,15 +82,15 @@ public override Models.Responses.Attribute Read(ref Utf8JsonReader reader, Type

if (type == 0)
{
return JsonSerializer.Deserialize(ref reader, typeof(LocationAttribute)) as LocationAttribute;
return JsonSerializer.Deserialize<LocationAttribute>(ref reader, options);
}
else if (type == 1)
{
return JsonSerializer.Deserialize(ref reader, typeof(AddressAttribute)) as AddressAttribute;
return JsonSerializer.Deserialize<AddressAttribute>(ref reader, options);
}
else
{
return JsonSerializer.Deserialize(ref reader, typeof(PlaceAttribute)) as PlaceAttribute;
return JsonSerializer.Deserialize<PlaceAttribute>(ref reader, options);
}
}

Expand All @@ -113,17 +113,17 @@ public override void Write(Utf8JsonWriter writer, Models.Responses.Attribute val
return;
}

if (value.GetType() == Location)
if (value.GetType() == LocationType)
{
JsonSerializer.Serialize(writer, value, Location);
JsonSerializer.Serialize(writer, value, LocationType, options);
}
else if (value.GetType() == Address)
else if (value.GetType() == AddressType)
{
JsonSerializer.Serialize(writer, value, Address);
JsonSerializer.Serialize(writer, value, AddressType, options);
}
else
{
JsonSerializer.Serialize(writer, value, Place);
JsonSerializer.Serialize(writer, value, PlaceType, options);
}
}
}
Expand Down
18 changes: 9 additions & 9 deletions src/Geo.Here/Converters/AutosuggestJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ namespace Geo.Here.Converters
/// </summary>
public class AutosuggestJsonConverter : JsonConverter<BaseLocation>
{
private static readonly Type Entity = typeof(AutosuggestEntityLocation);
private static readonly Type Query = typeof(AutosuggestQueryLocation);
private static readonly Type EntityType = typeof(AutosuggestEntityLocation);
private static readonly Type QueryType = typeof(AutosuggestQueryLocation);

/// <inheritdoc/>
public override BaseLocation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
Expand Down Expand Up @@ -47,8 +47,8 @@ public override BaseLocation Read(ref Utf8JsonReader reader, Type typeToConvert,
}

var isEntity = false;
var addressAttributeName = Entity.GetAttribute<JsonPropertyNameAttribute>(nameof(AutosuggestEntityLocation.Address))?.Name;
var hrefAttributeName = Query.GetAttribute<JsonPropertyNameAttribute>(nameof(AutosuggestQueryLocation.Href))?.Name;
var addressAttributeName = EntityType.GetAttribute<JsonPropertyNameAttribute>(nameof(AutosuggestEntityLocation.Address))?.Name;
var hrefAttributeName = QueryType.GetAttribute<JsonPropertyNameAttribute>(nameof(AutosuggestQueryLocation.Href))?.Name;

while (typeReader.Read())
{
Expand Down Expand Up @@ -79,11 +79,11 @@ public override BaseLocation Read(ref Utf8JsonReader reader, Type typeToConvert,

if (isEntity)
{
return JsonSerializer.Deserialize(ref reader, typeof(AutosuggestEntityLocation)) as AutosuggestEntityLocation;
return JsonSerializer.Deserialize<AutosuggestEntityLocation>(ref reader, options);
}
else
{
return JsonSerializer.Deserialize(ref reader, typeof(AutosuggestQueryLocation)) as AutosuggestQueryLocation;
return JsonSerializer.Deserialize<AutosuggestQueryLocation>(ref reader, options);
}
}

Expand All @@ -106,13 +106,13 @@ public override void Write(Utf8JsonWriter writer, BaseLocation value, JsonSerial
return;
}

if (value.GetType() == Entity)
if (value.GetType() == EntityType)
{
JsonSerializer.Serialize(writer, value, Entity);
JsonSerializer.Serialize(writer, value, EntityType, options);
}
else
{
JsonSerializer.Serialize(writer, value, Query);
JsonSerializer.Serialize(writer, value, QueryType, options);
}
}
}
Expand Down
160 changes: 90 additions & 70 deletions src/Geo.MapBox/Converters/ContextConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,129 @@ namespace Geo.MapBox.Converters
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Geo.Core;
using Geo.Core.Extensions;
using Geo.MapBox.Models.Responses;

/// <summary>
/// A converter for a <see cref="Dictionary{TKey, TValue}"/> to a <see cref="Context"/>.
/// </summary>
public class ContextConverter : JsonConverter
public class ContextConverter : JsonConverter<Context>
{
/// <inheritdoc />
public override bool CanConvert(Type objectType)
private static readonly Type ContextType = typeof(Context);
private static readonly Dictionary<string, string> JsonNameMapping = GetJsonNameMapping();

/// <inheritdoc/>
public override Context Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (objectType == null)
if (typeToConvert == null)
{
throw new ArgumentNullException(nameof(objectType));
throw new ArgumentNullException(nameof(typeToConvert));
}

return objectType == typeof(List<Context>);
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}

if (reader.TokenType == JsonTokenType.Null)
{
return null;
}

if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException(string.Format(CultureInfo.InvariantCulture, "Unexpected token while parsing the context. Expected to find an object, instead found {0}", reader.TokenType.GetName()));
}

var data = JsonSerializer.Deserialize<Dictionary<string, string>>(ref reader, options);

if (data is null)
{
return null;
}

return PopulateData(data, options);
}

/// <inheritdoc />
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
/// <inheritdoc/>
public override void Write(Utf8JsonWriter writer, Context value, JsonSerializerOptions options)
{
if (reader == null)
if (writer == null)
{
throw new ArgumentNullException(nameof(reader));
throw new ArgumentNullException(nameof(writer));
}

if (objectType == null)
if (options == null)
{
throw new ArgumentNullException(nameof(objectType));
throw new ArgumentNullException(nameof(options));
}

if (serializer == null)
if (value == null)
{
throw new ArgumentNullException(nameof(serializer));
writer.WriteNullValue();
return;
}

var token = JObject.Load(reader);
var contextInfo = token.ToObject<Dictionary<string, string>>();
JsonSerializer.Serialize(writer, value, options);
}

if (contextInfo is null)
private static Dictionary<string, string> GetJsonNameMapping()
{
var mapping = new Dictionary<string, string>();
foreach (var property in ContextType.GetProperties())
{
return null;
var attributeName = ContextType.GetAttribute<JsonPropertyNameAttribute>(property.Name)?.Name;
if (attributeName == null)
{
continue;
}

mapping.Add(property.Name, attributeName);
}

return mapping;
}

private static string GetString(Dictionary<string, string> data, string name)
{
data.TryGetValue(JsonNameMapping[name], out var value);
return value;
}

private Context PopulateData(Dictionary<string, string> data, JsonSerializerOptions options)
{
var context = new Context();
context.Id = GetString(data, nameof(Context.Id));
context.Wikidata = GetString(data, nameof(Context.Wikidata));
context.ShortCode = GetString(data, nameof(Context.ShortCode));
context.ContextText = GetContextText(data);

return context;
}

private IList<ContextText> GetContextText(Dictionary<string, string> data)
{
var texts = new List<ContextText>();

#if NETSTANDARD2_1_OR_GREATER
var languages = contextInfo.Where(x => x.Key.Contains(ContextFields.Language, StringComparison.OrdinalIgnoreCase));
var languages = data.Where(x => x.Key.Contains(ContextFields.Language, StringComparison.OrdinalIgnoreCase));
#else
var languages = contextInfo.Where(x => x.Key.Contains(ContextFields.Language));
var languages = data.Where(x => x.Key.Contains(ContextFields.Language));
#endif
if (!languages.Any())
{
// There are 2 cases here:
// Either there are no extra languages, only the default,
// or there is a context group without the language tags.
#if NETSTANDARD2_1_OR_GREATER
var textItems = contextInfo.Keys.Where(x => x.Contains("text", StringComparison.OrdinalIgnoreCase));
var textItems = data.Keys.Where(x => x.Contains("text", StringComparison.OrdinalIgnoreCase));
#else
var textItems = contextInfo.Keys.Where(x => x.Contains("text"));
var textItems = data.Keys.Where(x => x.Contains("text"));
#endif
if (textItems.Count() > 1)
{
Expand All @@ -84,78 +148,34 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
}
}

var context = new Context();
contextInfo.TryGetValue(ContextFields.Id, out var id);
context.Id = id;
contextInfo.TryGetValue(ContextFields.Wikidata, out var wikidata);
context.Wikidata = wikidata;
contextInfo.TryGetValue(ContextFields.ShortCode, out var shortCode);
context.ShortCode = shortCode;

// There will be {languages.Count()} items in this context group.
foreach (var language in languages)
{
var contextText = new ContextText();

var languageEnding = language.Key.Substring(8);
contextInfo.TryGetValue(string.Concat(ContextFields.Language, languageEnding), out var lang);
data.TryGetValue(string.Concat(ContextFields.Language, languageEnding), out var lang);
if (lang == null)
{
lang = language.Value;
}

contextText.Language = lang;
contextInfo.TryGetValue(string.Concat(ContextFields.Text, languageEnding), out var text);
data.TryGetValue(string.Concat(ContextFields.Text, languageEnding), out var text);
contextText.Text = text;
contextText.IsDefault = string.IsNullOrWhiteSpace(languageEnding);

context.ContextText.Add(contextText);
}

return context;
}

/// <inheritdoc />
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (writer == null)
{
throw new ArgumentNullException(nameof(writer));
}

if (value == null)
{
throw new ArgumentNullException(nameof(value));
}

if (serializer == null)
{
throw new ArgumentNullException(nameof(serializer));
texts.Add(contextText);
}

serializer.Serialize(writer, value);
return texts;
}

/// <summary>
/// A class containing the names of the fields in the context response JSON.
/// </summary>
private static class ContextFields
{
/// <summary>
/// Gets the id field name.
/// </summary>
public static string Id => "id";

/// <summary>
/// Gets the wikidata field name.
/// </summary>
public static string Wikidata => "wikidata";

/// <summary>
/// Gets the short code field name.
/// </summary>
public static string ShortCode => "short_code";

/// <summary>
/// Gets the language field name.
/// </summary>
Expand Down
Loading

0 comments on commit 4ed16e9

Please sign in to comment.