/* * Copyright (c) 2023 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; /// /// Compares the value of this error code to another and returns true if they are equal /// /// The value to compare /// True if the ERRNO value is equal to the current value public readonly bool Equals(ERRNO other) => ErrorCode == other.ErrorCode; /// /// Compares the value of this error code to another and returns true if they are equal. /// You should avoid this overload as it will box the value type. /// /// The instance to compare /// True if the ERRNO value is equal to the current value public readonly override bool Equals(object? obj) => obj is ERRNO other && Equals(other); /// /// Returns the hash code of the underlying value /// /// The hashcode of the current value 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() => 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) => ErrorCode.ToString(format); /// public readonly bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) => ErrorCode.TryFormat(destination, out charsWritten, format, provider); /// public readonly string ToString(string format, IFormatProvider? formatProvider) => ErrorCode.ToString(format, formatProvider); 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; } }