/// <summary>
/// <para>Returns true if <paramref name="value" /> is a true, 'Y', "yes", "true", "1", or '1'.</para>
/// <para>Returns false if <paramref name="value" /> is a false, 'N', "no", "false", or '0'.</para>
/// <para>A null will return false.</para>
/// </summary>
/// <param name="value"></param>
[Pure]
public static Boolean ToBoolean<T>( [CanBeNull] this T value ) {
switch ( value ) {
case null: return false;
case Boolean b: return b;
case Char c: return c.In( ParsingConstants.TrueChars );
case Int32 i: return i >= 1;
case String s when String.IsNullOrWhiteSpace( s ): return false;
case String s: {
var clean = s.Trimmed();
if ( clean is null ) {
return false;
}
if ( clean.In( ParsingConstants.TrueStrings ) ) {
return true;
}
if ( Boolean.TryParse( clean, out var result ) ) {
return result;
}
break;
}
}
var t = value.ToString();
if ( !String.IsNullOrWhiteSpace( t ) ) {
t = t.Trim();
if ( t.In( ParsingConstants.TrueStrings ) ) {
return true;
}
if ( t.In( ParsingConstants.FalseStrings ) ) {
return false;
}
if ( Boolean.TryParse( t, out var rest ) ) {
return rest;
}
}
return false;
}
[DebuggerStepThrough]
[Pure]
public static Boolean? ToBooleanOrNull<T>( [CanBeNull] this T value ) {
switch ( value ) {
case null: return default( Boolean? );
case Boolean b: return b;
case Char c: return c.In( ParsingConstants.TrueChars );
case Int32 i: return i >= 1;
case String s when String.IsNullOrWhiteSpace( s ): return default( Boolean? );
case String s: {
var trimmed = s.Trimmed();
if ( trimmed is null ) {
return default( Boolean? );
}
if ( trimmed.In( ParsingConstants.TrueStrings ) ) {
return true;
}
if ( trimmed.In( ParsingConstants.FalseStrings ) ) {
return default( Boolean? );
}
if ( Boolean.TryParse( trimmed, out var result ) ) {
return result;
}
break;
}
}
var t = value.ToString();
if ( String.IsNullOrWhiteSpace( t ) ) {
return default( Boolean? );
}
t = t.Trim();
if ( t.In( ParsingConstants.TrueStrings ) ) {
return true;
}
if ( t.In( ParsingConstants.FalseStrings ) ) {
return default( Boolean? );
}
return Boolean.TryParse( t, out var rest ) ? rest : default( Boolean? );
}
public static Boolean ToBooleanOrThrow<T>( [CanBeNull] this T value ) =>
value.ToBooleanOrNull() ?? throw new FormatException( $"Unable to convert {nameof( value ).SmartQuote()} [{value}] to a boolean value." );
/// <summary>Trim the ToString() of the object; returning null if null, empty, or whitespace.</summary>
/// <param name="self"></param>
/// <returns></returns>
[DebuggerStepThrough]
[CanBeNull]
[Pure]
public static String? Trimmed<T>( [CanBeNull] this T self ) =>
self switch {
null => default( String? ),
String s => s.Trim().NullIfEmpty(),
var _ => self.ToString()?.Trim().NullIfEmpty()
};
/// <summary>Returns null if <paramref name="self" /> is <see cref="String.IsNullOrEmpty" />.</summary>
/// <param name="self"></param>
/// <returns></returns>
[CanBeNull]
[DebuggerStepThrough]
[Pure]
public static String? NullIfEmpty( [CanBeNull] this String? self ) => String.IsNullOrEmpty( self ) ? null : self;
/// <summary>
/// N, 0, no, false, fail, failed, failure, bad
/// </summary>
[NotNull]
[ItemNotNull]
public static readonly String[] FalseStrings = {
"N", "0", "false", Boolean.FalseString, "fail", "failed", "stop", nameof( Status.Bad ), nameof( Status.Failure ), nameof( Status.No ),
nameof( Status.Negative )
};
/// <summary>
/// Y, 1
/// </summary>
[NotNull]
public static readonly Char[] TrueChars = {
'Y', '1'
};
/// <summary>
/// Y, 1, yes, true, Success, good, Go, Positive, Continue
/// </summary>
[NotNull]
[ItemNotNull]
public static readonly String[] TrueStrings = {
"Y", "1", "yes", "true", Boolean.TrueString, nameof( Status.Success ), "good", nameof( Status.Go ), nameof( Status.Positive ), nameof( Status.Continue ), nameof(Status.Okay)
};