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; } } }