< Summary

Information
Class: Anichron.Worker.Ingestion.Middlewares.ContentHashingMiddleware
Assembly: Anichron.Worker
File(s): /home/runner/work/anichron/anichron/src/Anichron.Worker/Ingestion/Middlewares/ContentHashingMiddleware.cs
Tag: 228_36821334185
Line coverage
86%
Covered lines: 13
Uncovered lines: 2
Coverable lines: 15
Total lines: 27
Line coverage: 86.6%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Order()100%210%
CanInvoke(...)100%210%
InvokeAsync()100%22100%
HashFileAsync()100%11100%

File(s)

/home/runner/work/anichron/anichron/src/Anichron.Worker/Ingestion/Middlewares/ContentHashingMiddleware.cs

#LineLine coverage
 1using Anichron.Worker.Ingestion.Pipeline;
 2using System.IO.Abstractions;
 3using System.IO.Hashing;
 4
 5namespace Anichron.Worker.Ingestion.Middlewares;
 6
 77internal sealed class ContentHashingMiddleware(IFileSystem fileSystem) : IIngestionMiddleware
 8{
 09    public int Order => IngestionOrder.ContentHashing;
 010    public bool CanInvoke(IngestionContext context) => true;
 11
 12    public async Task InvokeAsync(IngestionContext context, IngestionDelegate next, CancellationToken ct)
 713    {
 714        context.ContentHash = await HashFileAsync(context.Item.AbsolutePath, ct);
 715        if (context.Item.SecondaryFile is { } secondary)
 116            context.SecondaryHash = await HashFileAsync(secondary.AbsolutePath, ct);
 717        await next(context, ct);
 718    }
 19
 20    private async Task<string> HashFileAsync(string absolutePath, CancellationToken ct)
 821    {
 822        await using var stream = fileSystem.File.OpenRead(absolutePath);
 823        var hasher = new XxHash64();
 824        await hasher.AppendAsync(stream, ct);
 825        return Convert.ToHexStringLower(hasher.GetHashAndReset());
 826    }
 27}