| File: FakeRedactor.cs | Web Access |
| Project: src\src\Libraries\Microsoft.Extensions.Compliance.Testing\Microsoft.Extensions.Compliance.Testing.csproj (Microsoft.Extensions.Compliance.Testing) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Globalization; #if NET8_0_OR_GREATER using System.Text; #endif using System.Threading; using Microsoft.Extensions.Compliance.Redaction; using Microsoft.Extensions.Options; using Microsoft.Shared.Diagnostics; namespace Microsoft.Extensions.Compliance.Testing; /// <summary> /// Redactor designed for use in tests. /// </summary> public class FakeRedactor : Redactor { #if NET8_0_OR_GREATER private readonly CompositeFormat _format; #else private readonly string _format; #endif private int _redactedSoFar; /// <summary> /// Gets the collector of redaction events. /// </summary> public FakeRedactionCollector EventCollector { get; } /// <summary> /// Initializes a new instance of the <see cref="FakeRedactor"/> class. /// </summary> /// <param name="options">The options to control the redactor's behavior.</param> /// <param name="collector">Collects info about redacted values.</param> public FakeRedactor(IOptions<FakeRedactorOptions>? options = null, FakeRedactionCollector? collector = null) { var opt = options ?? Microsoft.Extensions.Options.Options.Create(new FakeRedactorOptions()); IValidateOptions<FakeRedactorOptions> validator = new FakeRedactorOptionsAutoValidator(); var r = validator.Validate(nameof(options), opt.Value); if (r.Succeeded) { validator = new FakeRedactorOptionsCustomValidator(); r = validator.Validate(nameof(options), opt.Value); } if (r.Failed) { Throw.ArgumentException(nameof(options), r.ToString()); } EventCollector = collector ?? new FakeRedactionCollector(); #if NET8_0_OR_GREATER _format = CompositeFormat.Parse(opt.Value.RedactionFormat); #else _format = opt.Value.RedactionFormat; #endif } /// <summary> /// Initializes a new instance of the <see cref="FakeRedactor"/> class. /// </summary> /// <param name="options">The options to control behavior of redactor.</param> /// <param name="collector">Collects info about redacted values.</param> /// <returns>New instance of <see cref="FakeRedactor"/>.</returns> public static FakeRedactor Create(FakeRedactorOptions? options = null, FakeRedactionCollector? collector = null) => new(Options.Options.Create(options ?? new FakeRedactorOptions()), collector); /// <inheritdoc/> public override int Redact(ReadOnlySpan<char> source, Span<char> destination) { var sourceString = source.ToString(); var str = string.Format(CultureInfo.InvariantCulture, _format, sourceString); Throw.IfBufferTooSmall(destination.Length, str.Length, nameof(destination)); str.AsSpan().CopyTo(destination); var order = Interlocked.Increment(ref _redactedSoFar); EventCollector.Append(new RedactedData(sourceString, destination.Slice(0, str.Length).ToString(), order)); return str.Length; } /// <inheritdoc/> public override int GetRedactedLength(ReadOnlySpan<char> input) { return string.Format(CultureInfo.InvariantCulture, _format, input.ToString()).Length; } }