mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-09 22:15:00 +03:00
Native Aot (#10295)
* Protect models * Json Context * YAML AOT-friendly optimization * Run the Test in AOT mode * Remove TaskScheduler * Clean build output * Workflows
This commit is contained in:
@@ -7,40 +7,45 @@ public class JsonUtils
|
||||
private static readonly JsonSerializerOptions _defaultDeserializeOptions = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
ReadCommentHandling = JsonCommentHandling.Skip
|
||||
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
TypeInfoResolver = AppJsonContext.Default,
|
||||
};
|
||||
|
||||
private static readonly JsonSerializerOptions _defaultSerializeOptions = new()
|
||||
{
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
TypeInfoResolver = AppJsonContext.Default,
|
||||
};
|
||||
|
||||
private static readonly JsonSerializerOptions _defaultSerializeNoIndentedOptions = new()
|
||||
{
|
||||
WriteIndented = false,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
TypeInfoResolver = AppJsonContext.Default,
|
||||
};
|
||||
|
||||
private static readonly JsonSerializerOptions _nullValueSerializeOptions = new()
|
||||
{
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
TypeInfoResolver = AppJsonContext.Default,
|
||||
};
|
||||
|
||||
private static readonly JsonSerializerOptions _nullValueSerializeNoIndentedOptions = new()
|
||||
{
|
||||
WriteIndented = false,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
TypeInfoResolver = AppJsonContext.Default,
|
||||
};
|
||||
|
||||
private static readonly JsonDocumentOptions _defaultDocumentOptions = new()
|
||||
{
|
||||
CommentHandling = JsonCommentHandling.Skip
|
||||
CommentHandling = JsonCommentHandling.Skip,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -109,7 +114,7 @@ public class JsonUtils
|
||||
/// <param name="indented"></param>
|
||||
/// <param name="nullValue"></param>
|
||||
/// <returns></returns>
|
||||
public static string Serialize(object? obj, bool indented = true, bool nullValue = false)
|
||||
public static string Serialize<T>(T? obj, bool indented = true, bool nullValue = false)
|
||||
{
|
||||
var result = string.Empty;
|
||||
try
|
||||
@@ -140,7 +145,7 @@ public class JsonUtils
|
||||
/// <param name="obj"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static string Serialize(object? obj, JsonSerializerOptions? options)
|
||||
public static string SerializeCamelCase<T>(T? obj)
|
||||
{
|
||||
var result = string.Empty;
|
||||
try
|
||||
@@ -149,7 +154,14 @@ public class JsonUtils
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = JsonSerializer.Serialize(obj, options ?? _defaultSerializeOptions);
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
TypeInfoResolver = AppJsonContext.Default,
|
||||
};
|
||||
result = JsonSerializer.Serialize(obj, options);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -162,9 +174,108 @@ public class JsonUtils
|
||||
/// SerializeToNode
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <param name="nullValue"></param>
|
||||
/// <returns></returns>
|
||||
public static JsonNode? SerializeToNode(object? obj, JsonSerializerOptions? options = null)
|
||||
public static JsonNode? SerializeToNode<T>(T? obj, bool nullValue = false)
|
||||
{
|
||||
var options = nullValue ? _nullValueSerializeOptions : _defaultSerializeOptions;
|
||||
return JsonSerializer.SerializeToNode(obj, options);
|
||||
}
|
||||
|
||||
public static JsonArray? SerializeToArray(IEnumerable<string>? values)
|
||||
{
|
||||
if (values is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var array = new JsonArray();
|
||||
foreach (var value in values)
|
||||
{
|
||||
var valueNode = JsonSerializer.SerializeToNode(value, _defaultSerializeOptions);
|
||||
array.Add(valueNode);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(Config))]
|
||||
[JsonSerializable(typeof(RulesItem))]
|
||||
[JsonSerializable(typeof(ProfileItem))]
|
||||
[JsonSerializable(typeof(List<RulesItem>))]
|
||||
[JsonSerializable(typeof(List<ProfileItem>))]
|
||||
[JsonSerializable(typeof(ProfileItemModel))]
|
||||
[JsonSerializable(typeof(List<ProfileItemModel>))]
|
||||
[JsonSerializable(typeof(RoutingTemplate))]
|
||||
[JsonSerializable(typeof(DNSItem))]
|
||||
[JsonSerializable(typeof(SimpleDNSItem))]
|
||||
[JsonSerializable(typeof(IPAPIInfo))]
|
||||
[JsonSerializable(typeof(SsSIP008))]
|
||||
[JsonSerializable(typeof(List<SsServer>))]
|
||||
[JsonSerializable(typeof(SsServer))]
|
||||
[JsonSerializable(typeof(VmessQRCode))]
|
||||
[JsonSerializable(typeof(ClashProxies))]
|
||||
[JsonSerializable(typeof(ClashProviders))]
|
||||
[JsonSerializable(typeof(ClashConnections))]
|
||||
[JsonSerializable(typeof(ProtocolExtraItem))]
|
||||
[JsonSerializable(typeof(TransportExtraItem))]
|
||||
[JsonSerializable(typeof(TrafficItem))]
|
||||
[JsonSerializable(typeof(V2rayMetricsVars))]
|
||||
[JsonSerializable(typeof(V2rayMetricsVarsLink))]
|
||||
[JsonSerializable(typeof(GitHubRelease))]
|
||||
[JsonSerializable(typeof(List<GitHubRelease>))]
|
||||
[JsonSerializable(typeof(ServerStatItem))]
|
||||
[JsonSerializable(typeof(WebDavItem))]
|
||||
[JsonSerializable(typeof(KeyEventItem))]
|
||||
[JsonSerializable(typeof(SubItem))]
|
||||
[JsonSerializable(typeof(SingboxConfig))]
|
||||
[JsonSerializable(typeof(Dns4Sbox))]
|
||||
[JsonSerializable(typeof(Inbound4Sbox))]
|
||||
[JsonSerializable(typeof(List<Inbound4Sbox>))]
|
||||
[JsonSerializable(typeof(Endpoints4Sbox))]
|
||||
[JsonSerializable(typeof(List<Endpoints4Sbox>))]
|
||||
[JsonSerializable(typeof(Outbound4Sbox))]
|
||||
[JsonSerializable(typeof(List<Outbound4Sbox>))]
|
||||
[JsonSerializable(typeof(Rule4Sbox))]
|
||||
[JsonSerializable(typeof(Ruleset4Sbox))]
|
||||
[JsonSerializable(typeof(List<Rule4Sbox>))]
|
||||
[JsonSerializable(typeof(List<Ruleset4Sbox>))]
|
||||
[JsonSerializable(typeof(V2rayConfig))]
|
||||
[JsonSerializable(typeof(Dns4Ray))]
|
||||
[JsonSerializable(typeof(DnsServer4Ray))]
|
||||
[JsonSerializable(typeof(Inbounds4Ray))]
|
||||
[JsonSerializable(typeof(List<Inbounds4Ray>))]
|
||||
[JsonSerializable(typeof(Outbounds4Ray))]
|
||||
[JsonSerializable(typeof(List<Outbounds4Ray>))]
|
||||
[JsonSerializable(typeof(RulesItem4Ray))]
|
||||
[JsonSerializable(typeof(List<RulesItem4Ray>))]
|
||||
[JsonSerializable(typeof(Finalmask4Ray))]
|
||||
[JsonSerializable(typeof(string))]
|
||||
[JsonSerializable(typeof(int))]
|
||||
[JsonSerializable(typeof(long))]
|
||||
[JsonSerializable(typeof(double))]
|
||||
[JsonSerializable(typeof(decimal))]
|
||||
[JsonSerializable(typeof(bool))]
|
||||
[JsonSerializable(typeof(Guid))]
|
||||
[JsonSerializable(typeof(DateTime))]
|
||||
[JsonSerializable(typeof(DateTimeOffset))]
|
||||
[JsonSerializable(typeof(TimeSpan))]
|
||||
[JsonSerializable(typeof(int?))]
|
||||
[JsonSerializable(typeof(long?))]
|
||||
[JsonSerializable(typeof(double?))]
|
||||
[JsonSerializable(typeof(bool?))]
|
||||
[JsonSerializable(typeof(DateTime?))]
|
||||
[JsonSerializable(typeof(Guid?))]
|
||||
[JsonSerializable(typeof(string[]))]
|
||||
[JsonSerializable(typeof(int[]))]
|
||||
[JsonSerializable(typeof(byte[]))]
|
||||
[JsonSerializable(typeof(List<string>))]
|
||||
[JsonSerializable(typeof(List<int>))]
|
||||
[JsonSerializable(typeof(Dictionary<string, string>))]
|
||||
[JsonSerializable(typeof(Dictionary<string, object>))]
|
||||
[JsonSerializable(typeof(object))]
|
||||
[JsonSerializable(typeof(JsonElement))]
|
||||
[JsonSerializable(typeof(JsonDocument))]
|
||||
[JsonSerializable(typeof(JsonNode))]
|
||||
[JsonSerializable(typeof(JsonObject))]
|
||||
[JsonSerializable(typeof(JsonArray))]
|
||||
internal partial class AppJsonContext : JsonSerializerContext;
|
||||
|
||||
@@ -348,10 +348,9 @@ public class Utils
|
||||
.ToList());
|
||||
}
|
||||
|
||||
public static List<string> GetEnumNames<TEnum>() where TEnum : Enum
|
||||
public static List<string> GetEnumNames<TEnum>() where TEnum : struct, Enum
|
||||
{
|
||||
return Enum.GetValues(typeof(TEnum))
|
||||
.Cast<TEnum>()
|
||||
return Enum.GetValues<TEnum>()
|
||||
.Select(e => e.ToString())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace ServiceLib.Common;
|
||||
|
||||
@@ -13,45 +12,57 @@ public class YamlUtils
|
||||
/// <summary>
|
||||
/// Deserialize
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static T FromYaml<T>(string str)
|
||||
public static YamlMappingNode FromYaml(string str)
|
||||
{
|
||||
var deserializer = new DeserializerBuilder()
|
||||
.WithNamingConvention(PascalCaseNamingConvention.Instance)
|
||||
.Build();
|
||||
//var deserializer = new DeserializerBuilder()
|
||||
// .WithNamingConvention(PascalCaseNamingConvention.Instance)
|
||||
// .Build();
|
||||
//try
|
||||
//{
|
||||
// var obj = deserializer.Deserialize<T>(str);
|
||||
// return obj;
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// Logging.SaveLog(_tag, ex);
|
||||
// return deserializer.Deserialize<T>("");
|
||||
//}
|
||||
try
|
||||
{
|
||||
var obj = deserializer.Deserialize<T>(str);
|
||||
return obj;
|
||||
var yaml = new YamlStream();
|
||||
using var reader = new StringReader(str);
|
||||
yaml.Load(reader);
|
||||
var rootNode = (YamlMappingNode)yaml.Documents[0].RootNode;
|
||||
return rootNode;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(_tag, ex);
|
||||
return deserializer.Deserialize<T>("");
|
||||
return new YamlMappingNode();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <param name="node"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToYaml(object? obj)
|
||||
public static string ToYaml(YamlMappingNode? node)
|
||||
{
|
||||
var result = string.Empty;
|
||||
if (obj == null)
|
||||
if (node == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
var serializer = new SerializerBuilder()
|
||||
.WithNamingConvention(HyphenatedNamingConvention.Instance)
|
||||
.Build();
|
||||
|
||||
try
|
||||
{
|
||||
result = serializer.Serialize(obj);
|
||||
var doc = new YamlDocument(node);
|
||||
var stream = new YamlStream(doc);
|
||||
using var writer = new StringWriter();
|
||||
stream.Save(writer, assignAnchors: false);
|
||||
result = writer.ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -64,9 +75,15 @@ public class YamlUtils
|
||||
{
|
||||
try
|
||||
{
|
||||
var mergingParser = new MergingParser(new Parser(new StringReader(str)));
|
||||
var obj = new DeserializerBuilder().Build().Deserialize(mergingParser);
|
||||
return ToYaml(obj);
|
||||
using var reader = new StringReader(str);
|
||||
var parser = new Parser(reader);
|
||||
var mergingParser = new MergingParser(parser);
|
||||
var yamlStream = new YamlStream();
|
||||
yamlStream.Load(mergingParser);
|
||||
using var writer = new StringWriter();
|
||||
yamlStream.Save(writer, assignAnchors: false);
|
||||
|
||||
return writer.ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user