init
This commit is contained in:
95
scripts/ApiModelSerializer.cs
Normal file
95
scripts/ApiModelSerializer.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using openF1Manager.scripts;
|
||||
|
||||
public static class ApiModelSerializer
|
||||
{
|
||||
public static string ToQueryString(object model, string baseAddress)
|
||||
{
|
||||
var query = System.Web.HttpUtility.ParseQueryString(string.Empty);
|
||||
foreach (var (key, value) in EnumerateKeyValues(model))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
query[key] = value;
|
||||
}
|
||||
|
||||
var queryString = query.ToString();
|
||||
return string.IsNullOrEmpty(queryString) ? baseAddress : $"{baseAddress}?{queryString}";
|
||||
}
|
||||
|
||||
public static void PopulateFromDictionary(object model, Godot.Collections.Dictionary dict)
|
||||
{
|
||||
var type = model.GetType();
|
||||
foreach (var prop in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
|
||||
{
|
||||
if (!prop.CanWrite) continue;
|
||||
|
||||
var attr = prop.GetCustomAttribute<ApiFieldAttribute>();
|
||||
var key = attr?.Key ?? ToSnakeCase(prop.Name);
|
||||
|
||||
// Try snake_case first, then camelCase fallbacks
|
||||
if (!TryGet(dict, key, out var str) && !TryGet(dict, SnakeToCamel(key), out str))
|
||||
continue;
|
||||
|
||||
// You can add type conversions if needed; here we only set strings
|
||||
if (prop.PropertyType == typeof(string) || prop.PropertyType == typeof(DateTime) || prop.PropertyType == typeof(int) || prop.PropertyType == typeof(float))
|
||||
prop.SetValue(model, str);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryGet(Dictionary dict, string key, out string value)
|
||||
{
|
||||
if (dict.ContainsKey(key) && dict[key].VariantType != Variant.Type.Nil)
|
||||
{
|
||||
value = dict[key].ToString();
|
||||
return true;
|
||||
}
|
||||
|
||||
value = string.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static IEnumerable<(string Key, string Value)> EnumerateKeyValues(object model)
|
||||
{
|
||||
var type = model.GetType();
|
||||
foreach (var prop in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
|
||||
{
|
||||
if (!prop.CanRead) continue;
|
||||
|
||||
var value = prop.GetValue(model)?.ToString();
|
||||
var attr = prop.GetCustomAttribute<ApiFieldAttribute>();
|
||||
var key = attr?.Key ?? ToSnakeCase(prop.Name);
|
||||
yield return (key, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static string ToSnakeCase(string name)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (int i = 0; i < name.Length; i++)
|
||||
{
|
||||
var c = name[i];
|
||||
sb.Append(i > 0 && char.IsUpper(c) ? "_" + char.ToLower(c) : c.ToString());
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string SnakeToCamel(string name)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append(char.ToLower(name[0]));
|
||||
for (int i = 1; i < name.Length; i++)
|
||||
{
|
||||
var c = name[i];
|
||||
sb.Append(char.IsUpper(c) ? char.ToLower(c) : c);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user