Skip to content

Commit

Permalink
Merge pull request #27 from jonsagara/feature/classes
Browse files Browse the repository at this point in the history
BarcodeParseResult now has an Errors property
  • Loading branch information
jonsagara authored Mar 12, 2024
2 parents df911b4 + fa128e9 commit af6b0c4
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 121 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@ if (parseResult.Card.FirstName.HasError)
}
```

You can iterate through all errors that occurred:

```csharp
if (parseResult.Errors.Count > 0)
{
foreach (var error in parseResult.Errors)
{
// All errors have a Message describing what went wrong.
Console.WriteLine($"Error: {error.Message}");

// Element-level errors will have an Element ID and the element's raw value.
Console.WriteLine($"Element ID: {error.ElementId}");
Console.WriteLine($"Raw Value: {error.RawValue}");
}
}
```

You can also check to see whether a field was present in the scanned ID text:

```csharp
Expand Down
63 changes: 8 additions & 55 deletions src/IdParser.Core/Barcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,6 @@

namespace IdParser.Core;

/// <summary>
/// Any element with an unrecognized 3-character element ID and its associated value.
/// </summary>
/// <param name="ElementId">The 3-character element ID.</param>
/// <param name="RawValue">The raw value from the scanned ID text.</param>
public record UnhandledElement(string ElementId, string? RawValue);

/// <summary>
/// Details about failure to parse or extract a meaningful value from an element's raw value obtained from
/// the scanned ID text.
/// </summary>
/// <param name="ElementId">The 3-character element ID.</param>
/// <param name="RawValue">The element's raw value from the scanned ID text.</param>
/// <param name="Error">A message describing the error that occurred.</param>
public record ElementParseError(string ElementId, string? RawValue, string Error);

/// <summary>
/// Contains the result of parsing a scanned ID: the ID card, a collection of unhandled fields, and any
/// field-level parsing errors that occurred.
/// </summary>
public class BarcodeParseResult
{
/// <summary>
/// Contains values of any elements extracted from the scanned ID text.
/// </summary>
public IdentificationCard Card { get; }

public IReadOnlyCollection<UnhandledElement> UnhandledElements { get; }

/// <summary>
/// Contains element-level errors that occurred while trying to extract a meaningful value from the element's raw value.
/// </summary>
public IReadOnlyCollection<ElementParseError> ElementParseErrors { get; }


public BarcodeParseResult(IdentificationCard card, IReadOnlyCollection<UnhandledElement> unhandledElements, IReadOnlyCollection<ElementParseError> elementParseErrors)
{
ArgumentNullException.ThrowIfNull(card);
ArgumentNullException.ThrowIfNull(unhandledElements);
ArgumentNullException.ThrowIfNull(elementParseErrors);

Card = card;
UnhandledElements = unhandledElements;
ElementParseErrors = elementParseErrors;
}
}

public static partial class Barcode
{
/// <summary>
Expand Down Expand Up @@ -138,7 +91,7 @@ public static BarcodeParseResult Parse(string rawPdf417Input, Validation validat
logger.UnhandledElementIds(string.Join(", ", populateResult.UnhandledElements.Select(ue => ue.ElementId)));
}

return new BarcodeParseResult(idCard, populateResult.UnhandledElements, populateResult.ElementErrors);
return new BarcodeParseResult(idCard, populateResult.UnhandledElements, populateResult.Errors);
}


Expand Down Expand Up @@ -442,12 +395,12 @@ private static ParseCountryResult ParseCountry(IssuerIdentificationNumber iin, A
}


private readonly record struct PopulateResult(List<UnhandledElement> UnhandledElements, List<ElementParseError> ElementErrors);
private readonly record struct PopulateResult(List<UnhandledElement> UnhandledElements, List<ParseError> Errors);

private static PopulateResult PopulateIdCard(IdentificationCard idCard, AAMVAVersion version, Country country, Dictionary<string, string?> subfileRecords, ILogger logger)
{
List<UnhandledElement> unhandledElements = new();
List<ElementParseError> elementErrors = new();
List<ParseError> errors = new();

foreach (var elementId in subfileRecords.Keys)
{
Expand All @@ -464,7 +417,7 @@ private static PopulateResult PopulateIdCard(IdentificationCard idCard, AAMVAVer
var parseAndSetResult = Parser.ParseAndSetIdCardElement(elementId: elementId, rawValue: rawValue, country, version, idCard);
if (parseAndSetResult.ElementHandled)
{
AddErrorIfParseAndSetFailed(parseAndSetResult, elementErrors);
AddErrorIfParseAndSetFailed(parseAndSetResult, errors);

// Element handled. No need for further processing.
continue;
Expand All @@ -475,7 +428,7 @@ private static PopulateResult PopulateIdCard(IdentificationCard idCard, AAMVAVer
parseAndSetResult = Parser.ParseAndSetDriversLicenseElement(elementId: elementId, rawValue: rawValue, country, version, driversLicense);
if (parseAndSetResult.ElementHandled)
{
AddErrorIfParseAndSetFailed(parseAndSetResult, elementErrors);
AddErrorIfParseAndSetFailed(parseAndSetResult, errors);

// Element handled. No need for further processing.
continue;
Expand All @@ -495,16 +448,16 @@ private static PopulateResult PopulateIdCard(IdentificationCard idCard, AAMVAVer
}
}

return new PopulateResult(unhandledElements, elementErrors);
return new PopulateResult(unhandledElements, errors);
}

private static void AddErrorIfParseAndSetFailed(Parser.ParseAndSetElementResult parseAndSetResult, List<ElementParseError> elementErrors)
private static void AddErrorIfParseAndSetFailed(Parser.ParseAndSetElementResult parseAndSetResult, List<ParseError> errors)
{
if (!parseAndSetResult.HasError)
{
return;
}

elementErrors.Add(parseAndSetResult.ElementParseError);
errors.Add(parseAndSetResult.Error);
}
}
35 changes: 35 additions & 0 deletions src/IdParser.Core/BarcodeParseResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace IdParser.Core;

/// <summary>
/// Contains the result of parsing a scanned ID: the ID card, a collection of unhandled fields, and any
/// field-level parsing errors that occurred.
/// </summary>
public class BarcodeParseResult
{
/// <summary>
/// Contains values of any elements extracted from the scanned ID text.
/// </summary>
public IdentificationCard Card { get; }

/// <summary>
/// Contains any unhandled element IDs and their raw values.
/// </summary>
public IReadOnlyCollection<UnhandledElement> UnhandledElements { get; }

/// <summary>
/// Contains errors that occurred while trying to parse the scanned ID text.
/// </summary>
public IReadOnlyCollection<ParseError> Errors { get; }


internal BarcodeParseResult(IdentificationCard card, IReadOnlyCollection<UnhandledElement> unhandledElements, IReadOnlyCollection<ParseError> errors)
{
ArgumentNullException.ThrowIfNull(card);
ArgumentNullException.ThrowIfNull(unhandledElements);
ArgumentNullException.ThrowIfNull(errors);

Card = card;
UnhandledElements = unhandledElements;
Errors = errors;
}
}
2 changes: 1 addition & 1 deletion src/IdParser.Core/IdParser.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>

<!-- NuGet -->
<Version>3.0.0-alpha2</Version>
<Version>3.0.0-beta1</Version>
<AssemblyVersion>3.0.0</AssemblyVersion>
<FileVersion>3.0.0</FileVersion>
<Authors>Connor O'Shea, Jon Sagara</Authors>
Expand Down
15 changes: 15 additions & 0 deletions src/IdParser.Core/ParseError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace IdParser.Core;

/// <summary>
/// Details about failure to parse or extract a meaningful value from an element's raw value obtained from
/// the scanned ID text.
/// </summary>
/// <remarks>
/// NOTE: Name ParseError instead of Error because otherwise the compiler complains: CA1716: Rename type
/// Error so that it no longer conflicts with the reserved language keyword 'Error'. Using a reserved keyword
/// as the name of a type makes it harder for consumers in other languages to use the type.
/// </remarks>
/// <param name="Message">A message describing the error that occurred.</param>
/// <param name="ElementId">If element-specific, the 3-character element ID; otherwise, null.</param>
/// <param name="RawValue">If element-specific, the element's raw value from the scanned ID text; otherwise, null.</param>
public record ParseError(string Message, string? ElementId, string? RawValue);
Loading

0 comments on commit af6b0c4

Please sign in to comment.