/*
* Copyright (c) 2022 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Utils
* File: ERRNO.cs
*
* ERRNO.cs is part of VNLib.Utils which is part of the larger
* VNLib collection of libraries and utilities.
*
* VNLib.Utils is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 2 of the License,
* or (at your option) any later version.
*
* VNLib.Utils is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/.
*/
using System;
using System.Runtime.InteropServices;
namespace VNLib.Utils
{
///
/// Implements a C style integer error code type. Size is platform dependent
///
[StructLayout(LayoutKind.Sequential)]
public readonly struct ERRNO : IEquatable, ISpanFormattable, IFormattable
{
///
/// Represents a successfull error code (true)
///
public static readonly ERRNO SUCCESS = true;
///
/// Represents a failure error code (false)
///
public static readonly ERRNO E_FAIL = false;
private readonly nint ErrorCode;
///
/// Creates a new from the specified error value
///
/// The value of the error to represent
public ERRNO(nint errno) => ErrorCode = errno;
///
/// Creates a new from an error code. null = 0 = false
///
/// Error code
public static implicit operator ERRNO(int errorVal) => new (errorVal);
///
/// Creates a new from an error code. null = 0 = false
///
/// Error code
public static explicit operator ERRNO(int? errorVal) => new(errorVal ?? 0);
///
/// Creates a new from a booleam, 1 if true, 0 if false
///
///
public static implicit operator ERRNO(bool errorVal) => new(errorVal ? 1 : 0);
///
/// Creates a new from a pointer value
///
/// The pointer value representing an error code
public static implicit operator ERRNO(nint errno) => new(errno);
///
/// Error value as integer. Value of supplied error code or if cast from boolean 1 if true, 0 if false
///
/// to get error code from
public static implicit operator int(ERRNO errorVal) => (int)errorVal.ErrorCode;
///
/// C style boolean conversion. false if 0, true otherwise
///
///
public static implicit operator bool(ERRNO errorVal) => errorVal != 0;
///
/// Creates a new from the value if the stored (nint) error code
///
/// The contating the pointer value
public static implicit operator IntPtr(ERRNO errno) => new(errno.ErrorCode);
///
/// Creates a new nint from the value if the stored error code
///
/// The contating the pointer value
public static implicit operator nint(ERRNO errno) => errno.ErrorCode;
public static ERRNO operator +(ERRNO err, int add) => new(err.ErrorCode + add);
public static ERRNO operator +(ERRNO err, nint add) => new(err.ErrorCode + add);
public static ERRNO operator ++(ERRNO err) => new(err.ErrorCode + 1);
public static ERRNO operator --(ERRNO err) => new(err.ErrorCode - 1);
public static ERRNO operator -(ERRNO err, int subtract) => new(err.ErrorCode - subtract);
public static ERRNO operator -(ERRNO err, nint subtract) => new(err.ErrorCode - subtract);
public static bool operator >(ERRNO err, ERRNO other) => err.ErrorCode > other.ErrorCode;
public static bool operator <(ERRNO err, ERRNO other) => err.ErrorCode < other.ErrorCode;
public static bool operator >=(ERRNO err, ERRNO other) => err.ErrorCode >= other.ErrorCode;
public static bool operator <=(ERRNO err, ERRNO other) => err.ErrorCode <= other.ErrorCode;
public static bool operator >(ERRNO err, int other) => err.ErrorCode > other;
public static bool operator <(ERRNO err, int other) => err.ErrorCode < other;
public static bool operator >=(ERRNO err, int other) => err.ErrorCode >= other;
public static bool operator <=(ERRNO err, int other) => err.ErrorCode <= other;
public static bool operator >(ERRNO err, nint other) => err.ErrorCode > other;
public static bool operator <(ERRNO err, nint other) => err.ErrorCode < other;
public static bool operator >=(ERRNO err, nint other) => err.ErrorCode >= other;
public static bool operator <=(ERRNO err, nint other) => err.ErrorCode <= other;
public static bool operator ==(ERRNO err, ERRNO other) => err.ErrorCode == other.ErrorCode;
public static bool operator !=(ERRNO err, ERRNO other) => err.ErrorCode != other.ErrorCode;
public static bool operator ==(ERRNO err, int other) => err.ErrorCode == other;
public static bool operator !=(ERRNO err, int other) => err.ErrorCode != other;
public static bool operator ==(ERRNO err, nint other) => err.ErrorCode == other;
public static bool operator !=(ERRNO err, nint other) => err.ErrorCode != other;
public readonly bool Equals(ERRNO other) => ErrorCode == other.ErrorCode;
public readonly override bool Equals(object? obj) => obj is ERRNO other && Equals(other);
public readonly override int GetHashCode() => ErrorCode.GetHashCode();
///
/// Attempts to parse the value of the character sequence as a new error code
///
/// The character sequence value to parse
/// The value
/// True if the value was successfully parsed, false othwerwise
public static bool TryParse(ReadOnlySpan value, out ERRNO result)
{
result = 0;
if (nint.TryParse(value, out nint res))
{
result = new ERRNO(res);
return true;
}
return false;
}
///
/// The integer error value of the current instance in radix 10
///
/// The radix 10 formatted error code
public readonly override string ToString()
{
//Return the string of the error code number
return ErrorCode.ToString();
}
///
/// Formats the internal nint error code as a string in specified format
///
/// The format to use
/// The formatted error code
public readonly string ToString(string format)
{
//Return the string of the error code number
return ErrorCode.ToString(format);
}
///
public readonly bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider provider)
{
return ErrorCode.TryFormat(destination, out charsWritten, format, provider);
}
///
public readonly string ToString(string format, IFormatProvider formatProvider)
{
return ErrorCode.ToString(format, formatProvider);
}
}
}