Skip to content

Commit

Permalink
😊 完善 新流变(粘土)对象只读功能设计
Browse files Browse the repository at this point in the history
  • Loading branch information
MonkSoul committed Jan 10, 2025
1 parent d4d98a9 commit cb5c969
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 58 deletions.
30 changes: 5 additions & 25 deletions framework/Furion.Pure/V5_Experience/Shapeless/Clay/Clay.Exports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,24 +381,7 @@ public bool Insert(int index, object? value)
// 检查是否是单一对象实例调用
ThrowIfMethodCalledOnSingleObject(nameof(Insert));

// 检查数组索引合法性
EnsureLegalArrayIndex(index, out _);

// 将 JsonCanvas 转换为 JsonArray 实例
var jsonArray = JsonCanvas.AsArray();

// 获取 JsonArray 长度
var count = jsonArray.Count;

// 检查索引大于数组长度
if (index > count)
{
return SetValue(index, value);
}

// 在指定位置插入
jsonArray.Insert(index, SerializeToNode(value, Options));
return true;
return SetValue(index, value, true);
}

/// <summary>
Expand All @@ -412,12 +395,7 @@ public bool Add(object? value)
// 检查是否是单一对象实例调用
ThrowIfMethodCalledOnSingleObject(nameof(Add));

// 将 JsonCanvas 转换为 JsonArray 实例
var jsonArray = JsonCanvas.AsArray();

// 在末尾处追加
jsonArray.Add(SerializeToNode(value, Options));
return true;
return SetValue(JsonCanvas.AsArray().Count, value);
}

/// <summary>
Expand Down Expand Up @@ -474,6 +452,9 @@ public bool Add(object? value)
/// </summary>
public void Clear()
{
// 确保当前实例不在只读模式下
EnsureNotReadOnlyBeforeModify();

// 检查是否是单一对象
if (IsObject)
{
Expand Down Expand Up @@ -654,7 +635,6 @@ public bool TryInsert(int index, object? value)
/// <summary>
/// 将 <see cref="Clay" /> 输出为 JSON 格式字符串
/// </summary>
/// <remarks>性能通常比 <see cref="ToString" /> 方式略高。</remarks>
/// <param name="jsonSerializerOptions">
/// <see cref="JsonSerializerOptions" />
/// </param>
Expand Down
42 changes: 38 additions & 4 deletions framework/Furion.Pure/V5_Experience/Shapeless/Clay/Clay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,15 @@ internal Clay(JsonNode? jsonNode, ClayOptions? options = null)
/// </summary>
/// <param name="keyOrIndex">键或索引</param>
/// <param name="value">值</param>
/// <param name="arrayInsert">是否作为在指定位置插入</param>
/// <returns>
/// <see cref="bool" />
/// </returns>
internal bool SetValue(object keyOrIndex, object? value)
internal bool SetValue(object keyOrIndex, object? value, bool arrayInsert = false)
{
// 确保当前实例不在只读模式下
EnsureNotReadOnlyBeforeModify();

// 空检查
ArgumentNullException.ThrowIfNull(keyOrIndex);

Expand All @@ -124,7 +128,7 @@ internal bool SetValue(object keyOrIndex, object? value)
// 根据键或索引设置值并获取结果
var result = IsObject
? SetNodeInObject(keyOrIndex, value, out var finalIndex)
: SetNodeInArray(keyOrIndex, value, out finalIndex);
: SetNodeInArray(keyOrIndex, value, out finalIndex, arrayInsert);

// 触发值变更之后事件
if (result)
Expand All @@ -144,6 +148,9 @@ internal bool SetValue(object keyOrIndex, object? value)
/// </returns>
internal bool RemoveValue(object keyOrIndex)
{
// 确保当前实例不在只读模式下
EnsureNotReadOnlyBeforeModify();

// 空检查
ArgumentNullException.ThrowIfNull(keyOrIndex);

Expand Down Expand Up @@ -305,10 +312,11 @@ internal bool SetNodeInObject(object key, object? value, out object finalKey)
/// <param name="index">索引</param>
/// <param name="value">元素值</param>
/// <param name="finalIndex">最终设置索引</param>
/// <param name="arrayInsert">是否作为在指定位置插入</param>
/// <returns>
/// <see cref="bool" />
/// </returns>
internal bool SetNodeInArray(object index, object? value, out object finalIndex)
internal bool SetNodeInArray(object index, object? value, out object finalIndex, bool arrayInsert = false)
{
// 检查数组索引合法性
EnsureLegalArrayIndex(index, out var intIndex);
Expand All @@ -322,7 +330,19 @@ internal bool SetNodeInArray(object index, object? value, out object finalIndex)
// 检查索引小于数组长度
if (intIndex < count)
{
jsonArray[intIndex] = SerializeToNode(value, Options);
// 将值序列化成 JsonNode 实例
var jsonNodeValue = SerializeToNode(value, Options);

// 替换指定位置的值
if (!arrayInsert)
{
jsonArray[intIndex] = jsonNodeValue;
}
// 在指定位置插入
else
{
jsonArray.Insert(intIndex, jsonNodeValue);
}
}
// 检查索引是否等于长度,如果是则追加
else if (intIndex == count)
Expand Down Expand Up @@ -666,6 +686,20 @@ internal static void EnsureLegalArrayIndex(object index, out int intIndex)
}
}

/// <summary>
/// 确保当前实例不在只读模式下。如果实例是只读的,则抛出异常
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
internal void EnsureNotReadOnlyBeforeModify()
{
// 检查是否是只读模式
if (Options.ReadOnly)
{
throw new InvalidOperationException(
"Operation cannot be performed because the Clay is in read-only mode.");
}
}

/// <summary>
/// 如果当前实例是单一对象且尝试调用不支持的操作,则抛出异常
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ public sealed class ClayOptions
/// </remarks>
public bool PropertyNameCaseInsensitive { get; set; }

/// <summary>
/// 是否是只读模式
/// </summary>
/// <remarks>默认值为:<c>false</c>。</remarks>
public bool ReadOnly { get; set; }

/// <summary>
/// JSON 序列化配置
/// </summary>
Expand Down
30 changes: 5 additions & 25 deletions framework/Furion/V5_Experience/Shapeless/Clay/Clay.Exports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,24 +381,7 @@ public bool Insert(int index, object? value)
// 检查是否是单一对象实例调用
ThrowIfMethodCalledOnSingleObject(nameof(Insert));

// 检查数组索引合法性
EnsureLegalArrayIndex(index, out _);

// 将 JsonCanvas 转换为 JsonArray 实例
var jsonArray = JsonCanvas.AsArray();

// 获取 JsonArray 长度
var count = jsonArray.Count;

// 检查索引大于数组长度
if (index > count)
{
return SetValue(index, value);
}

// 在指定位置插入
jsonArray.Insert(index, SerializeToNode(value, Options));
return true;
return SetValue(index, value, true);
}

/// <summary>
Expand All @@ -412,12 +395,7 @@ public bool Add(object? value)
// 检查是否是单一对象实例调用
ThrowIfMethodCalledOnSingleObject(nameof(Add));

// 将 JsonCanvas 转换为 JsonArray 实例
var jsonArray = JsonCanvas.AsArray();

// 在末尾处追加
jsonArray.Add(SerializeToNode(value, Options));
return true;
return SetValue(JsonCanvas.AsArray().Count, value);
}

/// <summary>
Expand Down Expand Up @@ -474,6 +452,9 @@ public bool Add(object? value)
/// </summary>
public void Clear()
{
// 确保当前实例不在只读模式下
EnsureNotReadOnlyBeforeModify();

// 检查是否是单一对象
if (IsObject)
{
Expand Down Expand Up @@ -654,7 +635,6 @@ public bool TryInsert(int index, object? value)
/// <summary>
/// 将 <see cref="Clay" /> 输出为 JSON 格式字符串
/// </summary>
/// <remarks>性能通常比 <see cref="ToString" /> 方式略高。</remarks>
/// <param name="jsonSerializerOptions">
/// <see cref="JsonSerializerOptions" />
/// </param>
Expand Down
42 changes: 38 additions & 4 deletions framework/Furion/V5_Experience/Shapeless/Clay/Clay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,15 @@ internal Clay(JsonNode? jsonNode, ClayOptions? options = null)
/// </summary>
/// <param name="keyOrIndex">键或索引</param>
/// <param name="value">值</param>
/// <param name="arrayInsert">是否作为在指定位置插入</param>
/// <returns>
/// <see cref="bool" />
/// </returns>
internal bool SetValue(object keyOrIndex, object? value)
internal bool SetValue(object keyOrIndex, object? value, bool arrayInsert = false)
{
// 确保当前实例不在只读模式下
EnsureNotReadOnlyBeforeModify();

// 空检查
ArgumentNullException.ThrowIfNull(keyOrIndex);

Expand All @@ -124,7 +128,7 @@ internal bool SetValue(object keyOrIndex, object? value)
// 根据键或索引设置值并获取结果
var result = IsObject
? SetNodeInObject(keyOrIndex, value, out var finalIndex)
: SetNodeInArray(keyOrIndex, value, out finalIndex);
: SetNodeInArray(keyOrIndex, value, out finalIndex, arrayInsert);

// 触发值变更之后事件
if (result)
Expand All @@ -144,6 +148,9 @@ internal bool SetValue(object keyOrIndex, object? value)
/// </returns>
internal bool RemoveValue(object keyOrIndex)
{
// 确保当前实例不在只读模式下
EnsureNotReadOnlyBeforeModify();

// 空检查
ArgumentNullException.ThrowIfNull(keyOrIndex);

Expand Down Expand Up @@ -305,10 +312,11 @@ internal bool SetNodeInObject(object key, object? value, out object finalKey)
/// <param name="index">索引</param>
/// <param name="value">元素值</param>
/// <param name="finalIndex">最终设置索引</param>
/// <param name="arrayInsert">是否作为在指定位置插入</param>
/// <returns>
/// <see cref="bool" />
/// </returns>
internal bool SetNodeInArray(object index, object? value, out object finalIndex)
internal bool SetNodeInArray(object index, object? value, out object finalIndex, bool arrayInsert = false)
{
// 检查数组索引合法性
EnsureLegalArrayIndex(index, out var intIndex);
Expand All @@ -322,7 +330,19 @@ internal bool SetNodeInArray(object index, object? value, out object finalIndex)
// 检查索引小于数组长度
if (intIndex < count)
{
jsonArray[intIndex] = SerializeToNode(value, Options);
// 将值序列化成 JsonNode 实例
var jsonNodeValue = SerializeToNode(value, Options);

// 替换指定位置的值
if (!arrayInsert)
{
jsonArray[intIndex] = jsonNodeValue;
}
// 在指定位置插入
else
{
jsonArray.Insert(intIndex, jsonNodeValue);
}
}
// 检查索引是否等于长度,如果是则追加
else if (intIndex == count)
Expand Down Expand Up @@ -666,6 +686,20 @@ internal static void EnsureLegalArrayIndex(object index, out int intIndex)
}
}

/// <summary>
/// 确保当前实例不在只读模式下。如果实例是只读的,则抛出异常
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
internal void EnsureNotReadOnlyBeforeModify()
{
// 检查是否是只读模式
if (Options.ReadOnly)
{
throw new InvalidOperationException(
"Operation cannot be performed because the Clay is in read-only mode.");
}
}

/// <summary>
/// 如果当前实例是单一对象且尝试调用不支持的操作,则抛出异常
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ public sealed class ClayOptions
/// </remarks>
public bool PropertyNameCaseInsensitive { get; set; }

/// <summary>
/// 是否是只读模式
/// </summary>
/// <remarks>默认值为:<c>false</c>。</remarks>
public bool ReadOnly { get; set; }

/// <summary>
/// JSON 序列化配置
/// </summary>
Expand Down

0 comments on commit cb5c969

Please sign in to comment.