/// <summary>
/// Attempt to convert the given object into a kOS encapsulation type (something
/// derived from kOS.Safe.Encapsulation.Structure), returning that instead.
/// This never throws exception or complains in any way if the conversion cannot happen.
/// Insted in that case it just silently ignores the request and returns the original object
/// reference unchanged. Thus it is safe to call it "just in case", even in places where it won't
/// always be necessary, or have an effect at all. You should use in anywhere you need to
/// ensure that a value a user's script might see on the stack or in a script variable is properly
/// wrapped in a kOS Structure, and not just a raw primitive like int or double.
/// </summary>
/// <param name="value">value to convert</param>
/// <returns>new converted value, or original value if conversion couldn't happen or was unnecesary</returns>
public static object FromPrimitive(object value)
{
if (value == null)
{
return(value); // If a null exists, let it pass through so it will bomb elsewhere, not here in FromPrimitive() where the exception message would be obtuse.
}
if (value is Structure)
{
return(value); // Conversion is unnecessary - it's already a Structure.
}
var convert = value as IConvertible;
if (convert == null)
{
return(value); // Conversion isn't even theoretically possible.
}
TypeCode code = convert.GetTypeCode();
switch (code)
{
case TypeCode.Boolean:
return(new BooleanValue(Convert.ToBoolean(convert)));
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return(ScalarValue.Create(Convert.ToDouble(convert)));
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return(ScalarValue.Create(Convert.ToInt32(convert)));
case TypeCode.String:
return(new StringValue(Convert.ToString(convert, CultureInfo.CurrentCulture)));
default:
break;
}
return(value); // Conversion is one this method didn't implement.
}