using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using Elsa.Extensions;
namespace Elsa.Api.Client.Extensions;
///
/// Provides extension methods for .
///
public static class JsonObjectExtensions
{
///
/// Returns true if the specified represents an activity.
///
public static bool IsActivity(this JsonObject obj)
{
return obj.ContainsKey("type") && obj.ContainsKey("id") && obj.ContainsKey("version");
}
///
/// Serializes the specified value to a .
///
/// The value to serialize.
/// The to use.
/// A representing the specified value.
public static JsonNode SerializeToNode(this object value, JsonSerializerOptions? options = null)
{
options ??= (new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
}).WithConverters(new JsonStringEnumConverter());
return JsonSerializer.SerializeToNode(value, options)!;
}
///
/// Serializes the specified value to a .
///
/// The value to serialize.
/// The to use.
/// A representing the specified value.
public static JsonArray SerializeToArray(this object value, JsonSerializerOptions? options = null)
{
options ??= new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
return JsonSerializer.SerializeToNode(value, options)!.AsArray();
}
///
/// Serializes the specified value to a .
///
/// The value to serialize.
/// The to use.
/// A representing the specified value.
public static JsonArray SerializeToArray(this IEnumerable value, JsonSerializerOptions? options = null)
{
options ??= new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
return JsonSerializer.SerializeToNode(value, options)!.AsArray();
}
///
/// Deserializes the specified to the specified type.
///
/// The to deserialize.
/// The to use.
/// The type to deserialize to.
/// The deserialized value.
public static T Deserialize(this JsonNode value, JsonSerializerOptions? options = null)
{
options ??= new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
if (value is JsonObject jsonObject)
return JsonSerializer.Deserialize(jsonObject, options)!;
if (value is JsonArray jsonArray)
return JsonSerializer.Deserialize(jsonArray, options)!;
if (typeof(T).IsEnum || (Nullable.GetUnderlyingType(typeof(T))?.IsEnum ?? false))
{
if (value.GetValueKind() == JsonValueKind.Null)
return default!;
return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T), value.ToString());
}
if (value is JsonValue jsonValue)
return jsonValue.GetValue();
throw new NotSupportedException($"Cannot deserialize {value.GetType()} to {typeof(T)}.");
}
///
/// Sets the property value of the specified model.
///
/// The model to set the property value on.
/// The value to set.
/// The path to the property.
public static void SetProperty(this JsonObject model, JsonNode? value, params string[] path)
{
model = GetPropertyContainer(model, path);
model[path.Last()] = value?.SerializeToNode();
}
///
/// Sets the property value of the specified model.
///
/// The model to set the property value on.
/// The value to set.
/// The path to the property.
public static void SetProperty(this JsonObject model, JsonArray? value, params string[] path)
{
model = GetPropertyContainer(model, path);
model[path.Last()] = value?.SerializeToNode();
}
///
/// Sets the property value of the specified model.
///
/// The model to set the property value on.
/// The value to set.
/// The path to the property.
public static void SetProperty(this JsonObject model, IEnumerable value, params string[] path)
{
model = GetPropertyContainer(model, path);
model[path.Last()] = new JsonArray(value.Select(x => x.SerializeToNode()).ToArray());
}
///
/// Gets the property value of the specified model.
///
/// The model to get the property value from.
/// The path to the property.
/// The property value.
public static JsonNode? GetProperty(this JsonObject model, params string[] path)
{
var currentModel = model;
foreach (var prop in path.SkipLast(1))
{
if (currentModel[prop] is not JsonObject value)
return null;
currentModel = value;
}
return currentModel[path.Last()];
}
///
/// Gets the property value of the specified model.
///
/// The model to get the property value from.
/// The path to the property.
/// The type to deserialize to.
/// The property value.
public static T? TryGetProperty(this JsonObject model, params string[] path)
{
try
{
return model.GetProperty(path);
}
catch (Exception e)
{
return default;
}
}
///
/// Gets the property value of the specified model.
///
/// The model to get the property value from.
/// The path to the property.
/// The type to deserialize to.
/// The property value.
public static T? GetProperty(this JsonObject model, params string[] path)
{
var property = GetProperty(model, path);
return property != null ? property.Deserialize() : default;
}
///
/// Gets the property value of the specified model.
///
/// The model to get the property value from.
/// The to use when deserializing.
/// The path to the property.
/// The type to deserialize to.
/// The property value.
public static T? GetProperty(this JsonObject model, JsonSerializerOptions options, params string[] path)
{
var property = GetProperty(model, path);
return property != null ? property.Deserialize(options) : default;
}
///
/// Returns the property container of the specified model.
///
/// The model to set the property value on.
/// The path to the property.
private static JsonObject GetPropertyContainer(this JsonObject model, params string[] path)
{
foreach (var prop in path.SkipLast(1))
{
var property = model[prop] as JsonObject ?? new JsonObject();
model[prop] = property;
model = property;
}
return model;
}
}