2024-12-09 21:11:46 +01:00
|
|
|
// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as published
|
|
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2024-07-12 17:12:24 +02:00
|
|
|
using System.Reflection;
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
using Newtonsoft.Json.Serialization;
|
|
|
|
|
|
|
|
namespace Foxnouns.Backend.Utils;
|
|
|
|
|
|
|
|
/// <summary>
|
2024-12-08 15:17:18 +01:00
|
|
|
/// <para>A base class used for PATCH requests which stores information on whether a key is explicitly set to null or not passed at all.</para>
|
|
|
|
/// <para>
|
2024-09-28 22:28:59 +02:00
|
|
|
/// HasProperty() should not be used for properties that cannot be set to null--a null value should be treated
|
|
|
|
/// as an unset value in those cases.
|
2024-12-08 15:17:18 +01:00
|
|
|
/// </para>
|
2024-07-12 17:12:24 +02:00
|
|
|
/// </summary>
|
|
|
|
public abstract class PatchRequest
|
|
|
|
{
|
|
|
|
private readonly HashSet<string> _properties = [];
|
2024-10-02 00:28:07 +02:00
|
|
|
|
2024-07-12 17:12:24 +02:00
|
|
|
public bool HasProperty(string propertyName) => _properties.Contains(propertyName);
|
2024-10-02 00:28:07 +02:00
|
|
|
|
2024-07-12 17:12:24 +02:00
|
|
|
public void SetHasProperty(string propertyName) => _properties.Add(propertyName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// A custom contract resolver to reduce the boilerplate needed to use <see cref="PatchRequest" />.
|
|
|
|
/// Based on this StackOverflow answer: https://stackoverflow.com/a/58748036
|
|
|
|
/// </summary>
|
|
|
|
public class PatchRequestContractResolver : DefaultContractResolver
|
|
|
|
{
|
2024-10-02 00:28:07 +02:00
|
|
|
protected override JsonProperty CreateProperty(
|
|
|
|
MemberInfo member,
|
|
|
|
MemberSerialization memberSerialization
|
|
|
|
)
|
2024-07-12 17:12:24 +02:00
|
|
|
{
|
2024-12-08 15:07:25 +01:00
|
|
|
JsonProperty prop = base.CreateProperty(member, memberSerialization);
|
2024-07-12 17:12:24 +02:00
|
|
|
|
|
|
|
prop.SetIsSpecified += (o, _) =>
|
|
|
|
{
|
2024-10-02 00:28:07 +02:00
|
|
|
if (o is not PatchRequest patchRequest)
|
|
|
|
return;
|
2024-07-12 17:12:24 +02:00
|
|
|
patchRequest.SetHasProperty(prop.UnderlyingName!);
|
|
|
|
};
|
|
|
|
|
|
|
|
return prop;
|
|
|
|
}
|
2024-10-02 00:28:07 +02:00
|
|
|
}
|