using System; using System.Threading; using System.Threading.Tasks; using StellaOps.Scanner.Analyzers.Lang.Rust.Internal; namespace StellaOps.Scanner.Analyzers.Lang.Rust; public sealed class RustLanguageAnalyzer : ILanguageAnalyzer { public string Id => "rust"; public string DisplayName => "Rust Analyzer (preview)"; public ValueTask AnalyzeAsync(LanguageAnalyzerContext context, LanguageComponentWriter writer, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(writer); cancellationToken.ThrowIfCancellationRequested(); var collection = RustAnalyzerCollector.Collect(context, cancellationToken); EmitRecords(Id, writer, collection.Crates); EmitRecords(Id, writer, collection.Heuristics); EmitRecords(Id, writer, collection.Fallbacks); return ValueTask.CompletedTask; } private static void EmitRecords(string analyzerId, LanguageComponentWriter writer, IReadOnlyList records) { foreach (var record in records) { if (record is null) { continue; } if (!string.IsNullOrEmpty(record.Purl)) { writer.AddFromPurl( analyzerId: analyzerId, purl: record.Purl!, name: record.Name, version: record.Version, type: record.Type, metadata: record.Metadata, evidence: record.Evidence, usedByEntrypoint: record.UsedByEntrypoint); } else { writer.AddFromExplicitKey( analyzerId: analyzerId, componentKey: record.ComponentKey, purl: null, name: record.Name, version: record.Version, type: record.Type, metadata: record.Metadata, evidence: record.Evidence, usedByEntrypoint: record.UsedByEntrypoint); } } } }