Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Create guard clauses #170

Merged
merged 3 commits into from
Jun 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public static IEnvReader AddDotEnv(this IServiceCollection services)
/// <returns>An instance that allows access to the environment variables.</returns>
public static IEnvReader AddDotEnv(this IServiceCollection services, params string[] paths)
{
_ = services ?? throw new ArgumentNullException(nameof(services));
ThrowHelper.ThrowIfNull(services, nameof(services));
ThrowHelper.ThrowIfNull(paths, nameof(paths));
ThrowHelper.ThrowIfEmptyCollection(paths, nameof(paths));
var envVars = Load(paths);
return services.AddEnvReader(envVars);
}
Expand Down Expand Up @@ -57,7 +59,9 @@ public static IEnvReader AddDotEnv(this IServiceCollection services, params stri
public static TSettings AddDotEnv<TSettings>(this IServiceCollection services, params string[] paths)
where TSettings : class, new()
{
_ = services ?? throw new ArgumentNullException(nameof(services));
ThrowHelper.ThrowIfNull(services, nameof(services));
ThrowHelper.ThrowIfNull(paths, nameof(paths));
ThrowHelper.ThrowIfEmptyCollection(paths, nameof(paths));
var envVars = Load(paths);
return services.AddTSettings<TSettings>(envVars);
}
Expand All @@ -73,7 +77,7 @@ public static TSettings AddDotEnv<TSettings>(this IServiceCollection services, p
/// <returns>An instance that allows access to the environment variables.</returns>
public static IEnvReader AddCustomEnv(this IServiceCollection services, string basePath = null, string environmentName = null)
{
_ = services ?? throw new ArgumentNullException(nameof(services));
ThrowHelper.ThrowIfNull(services, nameof(services));
var envVars = LoadEnv(basePath, environmentName);
return services.AddEnvReader(envVars);
}
Expand All @@ -91,7 +95,7 @@ public static IEnvReader AddCustomEnv(this IServiceCollection services, string b
public static TSettings AddCustomEnv<TSettings>(this IServiceCollection services, string basePath = null, string environmentName = null)
where TSettings : class, new()
{
_ = services ?? throw new ArgumentNullException(nameof(services));
ThrowHelper.ThrowIfNull(services, nameof(services));
var envVars = LoadEnv(basePath, environmentName);
return services.AddTSettings<TSettings>(envVars);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Common/Env.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static bool IsProduction()
/// <exception cref="ArgumentNullException"><c>environmentName</c> is <c>null</c>.</exception>
public static bool IsEnvironment(string environmentName)
{
_ = environmentName ?? throw new ArgumentNullException(nameof(environmentName));
ThrowHelper.ThrowIfNull(environmentName, nameof(environmentName));
return string.Equals(CurrentEnvironment, environmentName, StringComparison.OrdinalIgnoreCase);
}
}
57 changes: 57 additions & 0 deletions src/Common/ThrowHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using static DotEnv.Core.ExceptionMessages;

namespace DotEnv.Core;

/// <summary>
/// Helper methods to efficiently throw exceptions.
/// </summary>
internal class ThrowHelper
{
/// <summary>
/// Throws an <see cref="ArgumentNullException"/> if <c>argument</c> is <c>null</c>.
/// </summary>
/// <param name="argument">
/// The reference type argument to validate as non-null.
/// </param>
/// <param name="paramName">
/// The name of the parameter with which argument corresponds.
/// </param>
/// <exception cref="ArgumentNullException"></exception>
public static void ThrowIfNull(object argument, string paramName)
{
if(argument is null)
throw new ArgumentNullException(paramName);
}

/// <summary>
/// Throws an exception if <c>argument</c> is null, empty, or consists only of white-space characters.
/// </summary>
/// <param name="argument">
/// The string argument to validate.
/// </param>
/// <param name="paramName">
/// The name of the parameter with which argument corresponds.
/// </param>
/// <exception cref="ArgumentException"></exception>
public static void ThrowIfNullOrWhiteSpace(string argument, string paramName)
{
if (string.IsNullOrWhiteSpace(argument))
throw new ArgumentException(ArgumentIsNullOrWhiteSpaceMessage, paramName);
}

/// <summary>
/// Throws an exception if the <c>argument</c> is an empty collection.
/// </summary>
/// <param name="argument">
/// The collection argument to validate.
/// </param>
/// <param name="paramName">
/// The name of the parameter with which argument corresponds.
/// </param>
/// <exception cref="ArgumentException"></exception>
public static void ThrowIfEmptyCollection(IEnumerable<string> argument, string paramName)
{
if (argument.IsEmpty())
throw new ArgumentException(LengthOfParamsListIsZeroMessage, paramName);
}
}
1 change: 1 addition & 0 deletions src/DotEnv.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

<ItemGroup>
<InternalsVisibleTo Include="DotEnv.Core.Tests" />
<InternalsVisibleTo Include="DotEnv.Extensions.Microsoft.DI" />
</ItemGroup>

<ItemGroup>
Expand Down
24 changes: 10 additions & 14 deletions src/Loader/EnvLoader.ConfigurationMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,24 @@ public partial class EnvLoader
/// <inheritdoc />
public IEnvLoader SetDefaultEnvFileName(string envFileName)
{
_ = envFileName ?? throw new ArgumentNullException(nameof(envFileName));
ThrowHelper.ThrowIfNull(envFileName, nameof(envFileName));
_configuration.DefaultEnvFileName = envFileName;
return this;
}

/// <inheritdoc />
public IEnvLoader SetBasePath(string basePath)
{
_ = basePath ?? throw new ArgumentNullException(nameof(basePath));
ThrowHelper.ThrowIfNull(basePath, nameof(basePath));
_configuration.BasePath = basePath;
return this;
}

/// <inheritdoc />
public IEnvLoader AddEnvFiles(params string[] paths)
{
_ = paths ?? throw new ArgumentNullException(nameof(paths));
if (paths.IsEmpty())
throw new ArgumentException(LengthOfParamsListIsZeroMessage, nameof(paths));

ThrowHelper.ThrowIfNull(paths, nameof(paths));
ThrowHelper.ThrowIfEmptyCollection(paths, nameof(paths));
foreach (string path in paths)
AddEnvFile(path);
return this;
Expand All @@ -48,7 +46,7 @@ public IEnvLoader AddEnvFile(string path, Encoding encoding)
/// <inheritdoc />
public IEnvLoader AddEnvFile(string path, Encoding encoding, bool optional)
{
_ = path ?? throw new ArgumentNullException(nameof(path));
ThrowHelper.ThrowIfNull(path, nameof(path));
_configuration.EnvFiles.Add(new EnvFile { Path = path, Encoding = encoding, Optional = optional});
return this;
}
Expand All @@ -60,8 +58,8 @@ public IEnvLoader AddEnvFile(string path, string encodingName)
/// <inheritdoc />
public IEnvLoader AddEnvFile(string path, string encodingName, bool optional)
{
_ = path ?? throw new ArgumentNullException(nameof(path));
_ = encodingName ?? throw new ArgumentNullException(nameof(encodingName));
ThrowHelper.ThrowIfNull(path, nameof(path));
ThrowHelper.ThrowIfNull(encodingName, nameof(encodingName));
try
{
AddEnvFile(path, Encoding.GetEncoding(encodingName), optional);
Expand All @@ -80,7 +78,7 @@ public IEnvLoader AddEnvFile(string path, bool optional)
/// <inheritdoc />
public IEnvLoader SetEncoding(Encoding encoding)
{
_ = encoding ?? throw new ArgumentNullException(nameof(encoding));
ThrowHelper.ThrowIfNull(encoding, nameof(encoding));
_configuration.Encoding = encoding;
return this;
}
Expand Down Expand Up @@ -109,10 +107,8 @@ public IEnvLoader EnableFileNotFoundException()
/// <inheritdoc />
public IEnvLoader SetEnvironmentName(string envName)
{
_ = envName ?? throw new ArgumentNullException(nameof(envName));
if (string.IsNullOrWhiteSpace(envName))
throw new ArgumentException(ArgumentIsNullOrWhiteSpaceMessage, nameof(envName));

ThrowHelper.ThrowIfNull(envName, nameof(envName));
ThrowHelper.ThrowIfNullOrWhiteSpace(envName, nameof(envName));
_configuration.EnvironmentName = envName;
return this;
}
Expand Down
10 changes: 5 additions & 5 deletions src/Loader/EnvLoader.HelperMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public partial class EnvLoader
/// <exception cref="ArgumentNullException"><c>envFile</c> is <c>null</c>.</exception>
private void CheckIfEnvFileNotExistsAndIsNotOptional(EnvFile envFile)
{
_ = envFile ?? throw new ArgumentNullException(nameof(envFile));
ThrowHelper.ThrowIfNull(envFile, nameof(envFile));
if (!envFile.Exists && !envFile.Optional)
_validationResult.Add(errorMsg: string.Format(FileNotFoundMessage, envFile.Path));
}
Expand Down Expand Up @@ -61,7 +61,7 @@ private EnvValidationResult GetInstanceOfValidationResult()
/// <returns>true if the .env file exists, otherwise false.</returns>
private bool ReadAndParse(EnvFile envFile)
{
_ = envFile ?? throw new ArgumentNullException(nameof(envFile));
ThrowHelper.ThrowIfNull(envFile, nameof(envFile));
Result<string> result;
if (_configuration.SearchParentDirectories)
result = GetEnvFilePath(envFile.Path);
Expand Down Expand Up @@ -94,7 +94,7 @@ private bool ReadAndParse(EnvFile envFile)
/// <inheritdoc cref="Load()" path="/remarks" />
private Result<string> GetEnvFilePath(string envFileName)
{
_ = envFileName ?? throw new ArgumentNullException(nameof(envFileName));
ThrowHelper.ThrowIfNull(envFileName, nameof(envFileName));
string path;
if (Path.IsPathRooted(envFileName))
{
Expand Down Expand Up @@ -122,7 +122,7 @@ private Result<string> GetEnvFilePath(string envFileName)
/// <exception cref="ArgumentNullException"><c>envFile</c> is <c>null</c>.</exception>
private void SetConfigurationEnvFile(EnvFile envFile)
{
_ = envFile ?? throw new ArgumentNullException(nameof(envFile));
ThrowHelper.ThrowIfNull(envFile, nameof(envFile));
if (!Path.HasExtension(envFile.Path))
envFile.Path = Path.Combine(envFile.Path, _configuration.DefaultEnvFileName);

Expand All @@ -138,7 +138,7 @@ private void SetConfigurationEnvFile(EnvFile envFile)
/// <exception cref="ArgumentNullException"><c>envFilesNames</c> is <c>null</c>.</exception>
private void AddOptionalEnvFiles(params string[] envFilesNames)
{
_ = envFilesNames ?? throw new ArgumentNullException(nameof(envFilesNames));
ThrowHelper.ThrowIfNull(envFilesNames, nameof(envFilesNames));
foreach (string envFileName in envFilesNames)
_configuration.EnvFiles.Add(new EnvFile { Path = envFileName, Optional = true });
}
Expand Down
30 changes: 15 additions & 15 deletions src/Parser/EnvParser.HelperMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal void ThrowParserExceptionIfErrorsExist()
/// <returns><c>true</c> if the line is a comment, otherwise <c>false</c>.</returns>
private bool IsComment(string line)
{
_ = line ?? throw new ArgumentNullException(nameof(line));
ThrowHelper.ThrowIfNull(line, nameof(line));
line = _configuration.TrimStartComments ? line.TrimStart() : line;
return line[0] == _configuration.CommentChar;
}
Expand All @@ -42,7 +42,7 @@ private bool IsComment(string line)
/// <returns>A string without the inline comment.</returns>
private string RemoveInlineComment(string line, out string comment)
{
_ = line ?? throw new ArgumentNullException(nameof(line));
ThrowHelper.ThrowIfNull(line, nameof(line));
var substrings = line.Split(_configuration.InlineCommentChars, MaxCount, StringSplitOptions.None);
comment = substrings.Length == 1 ? null : substrings[1];
return substrings[0];
Expand All @@ -68,7 +68,7 @@ private string ConcatCommentWithValue(string value, string comment)
/// </returns>
private string TrimKey(string key)
{
_ = key ?? throw new ArgumentNullException(nameof(key));
ThrowHelper.ThrowIfNull(key, nameof(key));
key = _configuration.TrimStartKeys ? key.TrimStart() : key;
key = _configuration.TrimEndKeys ? key.TrimEnd() : key;
return key;
Expand All @@ -85,7 +85,7 @@ private string TrimKey(string key)
/// </returns>
private string TrimValue(string value)
{
_ = value ?? throw new ArgumentNullException(nameof(value));
ThrowHelper.ThrowIfNull(value, nameof(value));
value = _configuration.TrimStartValues ? value.TrimStart() : value;
value = _configuration.TrimEndValues ? value.TrimEnd() : value;
return value;
Expand All @@ -99,7 +99,7 @@ private string TrimValue(string value)
/// <returns>The key extracted.</returns>
private string ExtractKey(string line)
{
_ = line ?? throw new ArgumentNullException(nameof(line));
ThrowHelper.ThrowIfNull(line, nameof(line));
string key = line.Split(_configuration.DelimiterKeyValuePair, MaxCount)[0];
return key;
}
Expand All @@ -112,7 +112,7 @@ private string ExtractKey(string line)
/// <returns>The value extracted.</returns>
private string ExtractValue(string line)
{
_ = line ?? throw new ArgumentNullException(nameof(line));
ThrowHelper.ThrowIfNull(line, nameof(line));
string value = line.Split(_configuration.DelimiterKeyValuePair, MaxCount)[1];
return value;
}
Expand All @@ -125,7 +125,7 @@ private string ExtractValue(string line)
/// <returns><c>true</c> if the line has no the key-value pair, otherwise <c>false</c>.</returns>
private bool HasNoKeyValuePair(string line)
{
_ = line ?? throw new ArgumentNullException(nameof(line));
ThrowHelper.ThrowIfNull(line, nameof(line));
var keyValuePair = line.Split(_configuration.DelimiterKeyValuePair, MaxCount);
return keyValuePair.Length != 2 || string.IsNullOrWhiteSpace(keyValuePair[0]);
}
Expand All @@ -148,7 +148,7 @@ private string ConcatValues(string currentValue, string value)
/// <returns>A string with each environment variable replaced by its value.</returns>
private string ExpandEnvironmentVariables(string name, int currentLine)
{
_ = name ?? throw new ArgumentNullException(nameof(name));
ThrowHelper.ThrowIfNull(name, nameof(name));
var pattern = @"\$\{([^}]*)\}";
name = Regex.Replace(name, pattern, match =>
{
Expand Down Expand Up @@ -197,7 +197,7 @@ private string ExpandEnvironmentVariables(string name, int currentLine)
/// <returns><c>true</c> if the text is quoted, or <c>false</c>.</returns>
private bool IsQuoted(string text)
{
_ = text ?? throw new ArgumentNullException(nameof(text));
ThrowHelper.ThrowIfNull(text, nameof(text));
text = text.Trim();
if(text.Length <= 1)
return false;
Expand All @@ -213,7 +213,7 @@ private bool IsQuoted(string text)
/// <returns>A string without single or double quotes.</returns>
private string RemoveQuotes(string text)
{
_ = text ?? throw new ArgumentNullException(nameof(text));
ThrowHelper.ThrowIfNull(text, nameof(text));
return text.Trim().Trim([SingleQuote, DoubleQuote]);
}

Expand All @@ -226,8 +226,8 @@ private string RemoveQuotes(string text)
/// <returns>A key without the prefix.</returns>
private string RemovePrefixBeforeKey(string key, string prefix)
{
_ = key ?? throw new ArgumentNullException(nameof(key));
_ = prefix ?? throw new ArgumentNullException(nameof(prefix));
ThrowHelper.ThrowIfNull(key, nameof(key));
ThrowHelper.ThrowIfNull(prefix, nameof(prefix));
var aux = key;
key = key.TrimStart();
return key.IndexOf(prefix) == 0 ? key.Remove(0, prefix.Length) : aux;
Expand All @@ -243,7 +243,7 @@ private string RemovePrefixBeforeKey(string key, string prefix)
/// </returns>
private bool IsMultiline(string value)
{
_ = value ?? throw new ArgumentNullException(nameof(value));
ThrowHelper.ThrowIfNull(value, nameof(value));
value = value.Trim();
if(value.Length == 0)
return false;
Expand All @@ -268,8 +268,8 @@ private bool IsMultiline(string value)
/// </returns>
private Result<string> GetValuesMultilines(string[] lines, ref int index, string value)
{
_ = lines ?? throw new ArgumentNullException(nameof(lines));
_ = value ?? throw new ArgumentNullException(nameof(value));
ThrowHelper.ThrowIfNull(lines, nameof(lines));
ThrowHelper.ThrowIfNull(value, nameof(value));
value = value.TrimStart();
// Double or single-quoted.
char quoteChar = value[0];
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/EnvParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public IEnvironmentVariablesProvider Parse(string dataSource)
/// <inheritdoc />
public IEnvironmentVariablesProvider Parse(string dataSource, out EnvValidationResult result)
{
_ = dataSource ?? throw new ArgumentNullException(nameof(dataSource));
ThrowHelper.ThrowIfNull(dataSource, nameof(dataSource));
result = ValidationResult;
ParseStart(dataSource);
ThrowParserExceptionIfErrorsExist();
Expand Down
2 changes: 1 addition & 1 deletion src/Providers/DefaultEnvironmentProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public string this[string variable]
get => Environment.GetEnvironmentVariable(variable);
set
{
_ = variable ?? throw new ArgumentNullException(nameof(variable));
ThrowHelper.ThrowIfNull(variable, nameof(variable));
Environment.SetEnvironmentVariable(variable, value);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Providers/DictionaryProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public string this[string variable]
}
set
{
_ = variable ?? throw new ArgumentNullException(nameof(variable));
ThrowHelper.ThrowIfNull(variable, nameof(variable));
_keyValuePairs[variable] = value;
}
}
Expand Down
Loading
Loading