-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Strongly-typed product token with parse validation
- Loading branch information
Showing
12 changed files
with
596 additions
and
244 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using System; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace Robots.Txt.Parser; | ||
|
||
/// <summary> | ||
/// Crawler name, used as the User-agent value within a robots.txt file | ||
/// </summary> | ||
public partial class ProductToken : IEquatable<string>, IEquatable<ProductToken> | ||
{ | ||
public static readonly ProductToken Wildcard = new("*"); | ||
private static Regex ValidationPattern = ProductTokenValidationRegex(); | ||
|
||
private readonly string _value; | ||
|
||
private ProductToken(string value) => _value = value; | ||
|
||
public static ProductToken Parse(string value) | ||
{ | ||
if (value != Wildcard._value && !ValidationPattern.IsMatch(value)) | ||
{ | ||
throw new ArgumentOutOfRangeException( | ||
nameof(value), | ||
"Must contain only uppercase and lowercase letters (\"a-z\" and \"A-Z\"), underscores (\"_\"), and hyphens (\"-\")"); | ||
} | ||
|
||
return new ProductToken(value); | ||
} | ||
|
||
public static bool TryParse(string value, out ProductToken productToken) | ||
{ | ||
productToken = Wildcard; | ||
if (value != Wildcard._value && !ValidationPattern.IsMatch(value)) return false; | ||
productToken = new ProductToken(value); | ||
return true; | ||
} | ||
|
||
/* | ||
Crawlers set their own name, which is called a product token, to find relevant groups. | ||
The product token MUST contain only uppercase and lowercase letters ("a-z" and "A-Z"), underscores ("_"), and hyphens ("-"). | ||
*/ | ||
[GeneratedRegex("^[a-zA-Z-_]+$", RegexOptions.Compiled)] | ||
private static partial Regex ProductTokenValidationRegex(); | ||
|
||
/* | ||
Crawlers MUST use case-insensitive matching to find the group that matches the product token and then obey the rules of the group. | ||
*/ | ||
|
||
/// <summary> | ||
/// Assesses product token equality. Product tokens are case-insensitive. | ||
/// </summary> | ||
/// <param name="obj">Comparison value</param> | ||
/// <returns>True if the product token is equal; otherwise false</returns> | ||
public override bool Equals(object? obj) => | ||
obj is string otherString | ||
? Equals(otherString) | ||
: obj is ProductToken otherToken && Equals(otherToken); | ||
|
||
/// <summary> | ||
/// Assesses product token equality. Product tokens are case-insensitive. | ||
/// </summary> | ||
/// <param name="other">Comparison value</param> | ||
/// <returns>True if the product token is equal; otherwise false</returns> | ||
public bool Equals(string? other) => other is not null && _value.Equals(other, StringComparison.InvariantCultureIgnoreCase); | ||
|
||
/// <summary> | ||
/// Assesses product token equality. Product tokens are case-insensitive. | ||
/// </summary> | ||
/// <param name="other">Comparison value</param> | ||
/// <returns>True if the product token is equal; otherwise false</returns> | ||
public bool Equals(ProductToken? other) => | ||
other is not null && _value.Equals(other._value, StringComparison.InvariantCultureIgnoreCase); | ||
|
||
public override int GetHashCode() => _value.ToUpperInvariant().GetHashCode(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.