Skip to content

Instantly share code, notes, and snippets.

@Badabum
Created February 15, 2022 12:27
Show Gist options
  • Save Badabum/240c057ede0f12a5bd00062df8c2ba9d to your computer and use it in GitHub Desktop.
Save Badabum/240c057ede0f12a5bd00062df8c2ba9d to your computer and use it in GitHub Desktop.
public static class JsonPatchDocumentExtensions
{
public static Result Apply<TModel>(this JsonPatchDocument<TModel> jsonPatchDocument, TModel model) where TModel : class
{
Result applyingResult = Result.Ok();
void InCaseOfError(JsonPatchError jsonPatchError) => applyingResult = Result.Failure(jsonPatchError.ErrorMessage);
jsonPatchDocument.ApplyTo(model, InCaseOfError);
return applyingResult;
}
public static Result<TModel, AppError> ApplyOps<TModel>(this JsonPatchDocument<TModel> jsonPatchDocument, TModel model) where TModel : class
{
Result<TModel, AppError> applyingResult = Result.Success<TModel, AppError>(model);
void InCaseOfError(JsonPatchError jsonPatchError) => applyingResult = Result.Failure<TModel, AppError>(new AppError(jsonPatchError.ErrorMessage));
jsonPatchDocument.ApplyTo(model, InCaseOfError);
return applyingResult
.Map(_ => model);
}
public static bool ModifiesProperty<TModel>(this JsonPatchDocument<TModel> document, string propertyName)
where TModel : class
=> propertyName.Exists() && document.GetUpdatingProperties().Contains(propertyName);
public static T GetUpdatedValue<TModel, T>(this JsonPatchDocument<TModel> document, string propertyName)
where TModel : class
{
var op = document.Operations.Find(op => op.path.Replace("/", string.Empty).Equals(propertyName));
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(op.value));
}
public static string[] GetUpdatingProperties(this IJsonPatchDocument jsonPatchDocument)
=> jsonPatchDocument.GetOperations().Select(op => op.path.Replace("/", string.Empty)).ToArray();
public static HashSet<string> GetUpdatedProperties<TTarget>(this JsonPatchDocument<TTarget> jsonPatchDocument)
where TTarget : class => GetUpdatingProperties(jsonPatchDocument)
.Select(GetRealPropertyName<TTarget>)
.ToHashSet();
private static string GetRealPropertyName<TTarget>(string jsonPropertyName)
{
PropertyInfo matchingProperty = typeof(TTarget)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.FirstOrDefault(prop => prop.Name.Equals(jsonPropertyName) || HasJsonPropertyAttribute(prop, jsonPropertyName));
return matchingProperty.Name;
}
private static bool HasJsonPropertyAttribute(PropertyInfo propInfo, string jsonPropName)
{
JsonPropertyAttribute attribute = propInfo.GetCustomAttribute<JsonPropertyAttribute>();
if (attribute == null)
return false;
return attribute.PropertyName.Exists() &&
attribute.PropertyName.Equals(jsonPropName, StringComparison.OrdinalIgnoreCase);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment