using System;
using System.Globalization;
using Newtonsoft.Json.Linq;
namespace MCPForUnity.Editor.Helpers
{
///
/// Utility class for coercing JSON parameter values to strongly-typed values.
/// Handles various input formats (strings, numbers, booleans) gracefully.
///
public static class ParamCoercion
{
///
/// Coerces a JToken to an integer value, handling strings and floats.
///
/// The JSON token to coerce
/// Default value if coercion fails
/// The coerced integer value or default
public static int CoerceInt(JToken token, int defaultValue)
{
if (token == null || token.Type == JTokenType.Null)
return defaultValue;
try
{
if (token.Type == JTokenType.Integer)
return token.Value();
var s = token.ToString().Trim();
if (s.Length == 0)
return defaultValue;
if (int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out var i))
return i;
if (double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var d))
return (int)d;
}
catch
{
// Swallow and return default
}
return defaultValue;
}
///
/// Coerces a JToken to a boolean value, handling strings like "true", "1", etc.
///
/// The JSON token to coerce
/// Default value if coercion fails
/// The coerced boolean value or default
public static bool CoerceBool(JToken token, bool defaultValue)
{
if (token == null || token.Type == JTokenType.Null)
return defaultValue;
try
{
if (token.Type == JTokenType.Boolean)
return token.Value();
var s = token.ToString().Trim().ToLowerInvariant();
if (s.Length == 0)
return defaultValue;
if (bool.TryParse(s, out var b))
return b;
if (s == "1" || s == "yes" || s == "on")
return true;
if (s == "0" || s == "no" || s == "off")
return false;
}
catch
{
// Swallow and return default
}
return defaultValue;
}
///
/// Coerces a JToken to a float value, handling strings and integers.
///
/// The JSON token to coerce
/// Default value if coercion fails
/// The coerced float value or default
public static float CoerceFloat(JToken token, float defaultValue)
{
if (token == null || token.Type == JTokenType.Null)
return defaultValue;
try
{
if (token.Type == JTokenType.Float || token.Type == JTokenType.Integer)
return token.Value();
var s = token.ToString().Trim();
if (s.Length == 0)
return defaultValue;
if (float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var f))
return f;
}
catch
{
// Swallow and return default
}
return defaultValue;
}
///
/// Coerces a JToken to a string value, with null handling.
///
/// The JSON token to coerce
/// Default value if null or empty
/// The string value or default
public static string CoerceString(JToken token, string defaultValue = null)
{
if (token == null || token.Type == JTokenType.Null)
return defaultValue;
var s = token.ToString();
return string.IsNullOrEmpty(s) ? defaultValue : s;
}
///
/// Coerces a JToken to an enum value, handling strings.
///
/// The enum type
/// The JSON token to coerce
/// Default value if coercion fails
/// The coerced enum value or default
public static T CoerceEnum(JToken token, T defaultValue) where T : struct, Enum
{
if (token == null || token.Type == JTokenType.Null)
return defaultValue;
try
{
var s = token.ToString().Trim();
if (s.Length == 0)
return defaultValue;
if (Enum.TryParse(s, ignoreCase: true, out var result))
return result;
}
catch
{
// Swallow and return default
}
return defaultValue;
}
}
}