using System;

namespace _Core
{
    public class Result<T, U> where U : Exception
    {
        internal class Success : Result<T, U>
        {
            public T Value { get; private set; }

            public Success(T value)
            {
                Value = value;
            }
        }

        public class Fail : Result<T, U>
        {
            public U Value { get; private set; }

            public Fail(U error)
            {
                Value = error;
            }
        }

        public static Result<T, U> CreateSuccess(T value)
        {
            return new Success(value);
        }

        public static Fail CreateFail(U e)
        {
            return new Fail(e);
        }

        public bool IsSuccess
        {
            get
            {
                return this is Success;
            }
        }

        public T Data
        {
            get
            {
                if (this is Success success)
                {
                    return success.Value;
                }
                else if (this is Fail fail)
                {
                    throw fail.Value;
                }
                return default;
            }
        }

        public U Error
        {
            get
            {
                if (this is Fail fail)
                {
                    return fail.Value;
                }
                return null;
            }
        }
    }
}
