using System.Security; namespace StellaOps.Scanner.Analyzers.Lang.Rust.Internal; internal readonly struct RustFileCacheKey : IEquatable { private readonly string _normalizedPath; private readonly long _length; private readonly long _lastWriteTicks; private RustFileCacheKey(string normalizedPath, long length, long lastWriteTicks) { _normalizedPath = normalizedPath; _length = length; _lastWriteTicks = lastWriteTicks; } public static bool TryCreate(string path, out RustFileCacheKey key) { key = default; if (string.IsNullOrWhiteSpace(path)) { return false; } try { var info = new FileInfo(path); if (!info.Exists) { return false; } var normalizedPath = OperatingSystem.IsWindows() ? info.FullName.ToLowerInvariant() : info.FullName; key = new RustFileCacheKey(normalizedPath, info.Length, info.LastWriteTimeUtc.Ticks); return true; } catch (IOException) { return false; } catch (UnauthorizedAccessException) { return false; } catch (SecurityException) { return false; } catch (ArgumentException) { return false; } catch (NotSupportedException) { return false; } } public bool Equals(RustFileCacheKey other) => _length == other._length && _lastWriteTicks == other._lastWriteTicks && string.Equals(_normalizedPath, other._normalizedPath, StringComparison.Ordinal); public override bool Equals(object? obj) => obj is RustFileCacheKey other && Equals(other); public override int GetHashCode() => HashCode.Combine(_normalizedPath, _length, _lastWriteTicks); }