Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 51 additions & 8 deletions src/Sentry/MeasurementUnit.cs
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought:

This is a similar implementation a coding agent on my end suggested when I gave it a try when looking at it with a friend of mine just last weekend 😉.

I'm not too certain if I'm happy with this approach, though:

  • the size of the struct is increasing
  • we embed more data into the assembly (via the string-arrays)

On the other hand, this (or a similar) implementation is necessary, in order to not change the IEquatable-semantics.

We were then experimenting with the struct only having a string field,
but that would change the Equality-semantics, where

  • MeasurementUnit.Duration.Millisecond == MeasurementUnit.Custom("millisecond")
    • old/this: would not be equal, because constructed differently
    • only with string field: would now become equal, being a behavioral change

Copy link
Copy Markdown
Member

@Flash0ver Flash0ver May 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait ... actually ... I believe I am wrong concerning the size ... at least partially wrong

  • previous
    • System.Enum + System.String
    • on 64-bit: 8-byte-reference + 8-byte reference = 16B
    • on 32-bit: 4-byte-reference + 4-byte reference = 8B
  • this change
    • UnitKind enum (byte) + System.Int32 + System.String
    • on 64-bit: 1-byte enum + 4-byte int + 3-byte padding, 8-byte reference = 16B
    • on 32-bit: 1-byte enum + 3-byte padding + 4-byte int + 4-byte reference + padding = 12B

So we are only increasing the size of the struct by 4B on 32-bit systems/processes.

Yeah ... that's neglectable considering we no longer box to System.Enum.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

about the Equals-Semantics

If we would only keep a string field, assigning the string via a switch on constructions, we would simplify the code, reduce the struct size to 4B/8B (32-/64-bit systems); but we would change the Equals, as it would no longer matter whether the MeasurementUnit was constructed via MeasurementUnit.Custom or the respective implicit-ennum-conversion.

This being a behavioral change, we could simplify MeasurementUnit in the next Major ... or should we keep the Equals-Behavior as is, where there is a difference how the MeasurementUnit was constructed.

What do you think?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To err on the side of caution (since this API is probably quite widely used already), maybe we delay the behavioural change (and saving the extra 4B) until the next major release.

Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,50 @@
/// <seealso href="https://getsentry.github.io/relay/relay_metrics/enum.MetricUnit.html"/>
public readonly partial struct MeasurementUnit : IEquatable<MeasurementUnit>
{
private readonly Enum? _unit;
private readonly UnitKind _kind;
private readonly int _value;
private readonly string? _name;

private MeasurementUnit(Enum unit)
private enum UnitKind : byte
{
_unit = unit;
None = 0,
Duration = 1,
Information = 2,
Fraction = 3,
Custom = 4
}

private static readonly string[] DurationNames = Enum.GetNames<Duration>();

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Trim analysis

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / MSBuild

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / MSBuild

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / MSBuild

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 22 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

private static readonly string[] InformationNames = Enum.GetNames<Information>();

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Trim analysis

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / MSBuild

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / MSBuild

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / MSBuild

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 24 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

private static readonly string[] FractionNames = Enum.GetNames<Fraction>();

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View check run for this annotation

@sentry/warden / warden: find-bugs

GetPredefinedName returns PascalCase names instead of lowercase, changing serialized output

The new implementation uses `Enum.GetNames<Duration>()` (etc.) to precompute names, but `Enum.GetNames<T>()` returns names exactly as declared in the enum (PascalCase like "Second", "Byte", "Percent"). The previous implementation used `_unit.ToString().ToLowerInvariant()` which lowercased them. This regresses the public serialized form sent to Sentry from e.g. "second" to "Second", breaks existing tests (MeasurementUnitTests asserts "second"/"byte"/"percent"), and changes what Sentry receives via `ToString()`/`ToNullableString()`. The PR claims tests pass, but `CanUseDurationUnits`, `CanUseInformationUnits`, and `CanUseFractionUnits` would all fail with this code.

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Trim analysis

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-musl-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (linux-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / Analyze

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-x64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (win-arm64)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / MSBuild

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / MSBuild

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / MSBuild

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments

Check failure on line 26 in src/Sentry/MeasurementUnit.cs

View workflow job for this annotation

GitHub Actions / .NET (macos)

The non-generic method 'Enum.GetNames(Type)' cannot be used with type arguments
Comment thread
sentry-warden[bot] marked this conversation as resolved.
Outdated

private MeasurementUnit(Duration unit)
{
_kind = UnitKind.Duration;
_value = (int)unit;
_name = null;
}

private MeasurementUnit(Information unit)
{
_kind = UnitKind.Information;
_value = (int)unit;
_name = null;
}

private MeasurementUnit(Fraction unit)
{
_kind = UnitKind.Fraction;
_value = (int)unit;
_name = null;
}

private MeasurementUnit(string name)
{
_unit = null;
_kind = UnitKind.Custom;
_value = default;
_name = name;
}

Expand Down Expand Up @@ -70,21 +102,32 @@
return Custom(name);
}

private string? GetPredefinedName()
{
return _kind switch
{
UnitKind.Duration when (uint)_value < (uint)DurationNames.Length => DurationNames[_value],
UnitKind.Information when (uint)_value < (uint)InformationNames.Length => InformationNames[_value],
UnitKind.Fraction when (uint)_value < (uint)FractionNames.Length => FractionNames[_value],

Check failure on line 111 in src/Sentry/MeasurementUnit.cs

View check run for this annotation

@sentry/warden / warden: find-bugs

[9AB-NUT] GetPredefinedName returns PascalCase names instead of lowercase, changing serialized output (additional location)

The new implementation uses `Enum.GetNames<Duration>()` (etc.) to precompute names, but `Enum.GetNames<T>()` returns names exactly as declared in the enum (PascalCase like "Second", "Byte", "Percent"). The previous implementation used `_unit.ToString().ToLowerInvariant()` which lowercased them. This regresses the public serialized form sent to Sentry from e.g. "second" to "Second", breaks existing tests (MeasurementUnitTests asserts "second"/"byte"/"percent"), and changes what Sentry receives via `ToString()`/`ToNullableString()`. The PR claims tests pass, but `CanUseDurationUnits`, `CanUseInformationUnits`, and `CanUseFractionUnits` would all fail with this code.
_ => null
};
}

/// <summary>
/// Returns the string representation of the measurement unit, as it will be sent to Sentry.
/// </summary>
public override string ToString() => _unit?.ToString().ToLowerInvariant() ?? _name ?? "";
public override string ToString() => ToNullableString() ?? "";

internal string? ToNullableString() => _unit?.ToString().ToLowerInvariant() ?? _name;
internal string? ToNullableString() => _name ?? GetPredefinedName();

/// <inheritdoc />
public bool Equals(MeasurementUnit other) => Equals(_unit, other._unit) && _name == other._name;
public bool Equals(MeasurementUnit other) => _kind == other._kind && _value == other._value && _name == other._name;

/// <inheritdoc />
public override bool Equals(object? obj) => obj is MeasurementUnit other && Equals(other);

/// <inheritdoc />
public override int GetHashCode() => HashCode.Combine(_unit, _name, _unit?.GetType());
public override int GetHashCode() => HashCode.Combine(_kind, _value, _name);

/// <summary>
/// Returns true if the operands are equal.
Expand Down
Loading