using TUnit.Mocks.Matchers;
namespace TUnit.Mocks.Arguments;
///
/// Represents a typed argument matcher used in mock setup and verification expressions.
/// Implicitly converts from raw values for convenient inline usage.
/// Every Arg supports value capture — store it in a variable and read
/// after the mock is exercised.
///
/// The type of the argument being matched.
public readonly struct Arg
{
private readonly CapturingMatcher _capturingMatcher;
/// Gets the argument matcher. Public for generated code access. Not intended for direct use.
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public IArgumentMatcher Matcher => _capturingMatcher;
/// Creates an Arg with a matcher. Public for generated code access. Not intended for direct use.
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public Arg(IArgumentMatcher matcher)
{
_capturingMatcher = new CapturingMatcher(matcher);
}
/// Gets all captured values in order of capture.
public IReadOnlyList Values => _capturingMatcher.CapturedValues;
/// Gets the most recently captured value, or default if none captured.
public T? Latest => _capturingMatcher.Latest;
/// Implicitly converts a raw value to an using exact equality matching.
/// The value to match against.
///
/// When is itself a boxed — e.g. Is(1)
/// converted into an Arg<object> slot, which could never match. Thrown by
/// .
///
public static implicit operator Arg(T value) => new(new ExactMatcher(value));
/// Implicitly converts a predicate to an using predicate matching.
/// The predicate that determines whether an argument matches.
public static implicit operator Arg(Func predicate) => new(new PredicateMatcher(predicate!));
public static implicit operator Arg(AnyArg _) => new(AnyMatcher.Instance);
/// Converts into a type matcher for this parameter type.
public static implicit operator Arg(OfTypeArg ofType) => new(new TypeMatcher(ofType.Type));
/// Converts into a reference-equality matcher for this parameter type.
public static implicit operator Arg(SameAsArg sameAs) => new(new ReferenceEqualsMatcher(sameAs.Reference));
}