FERS 0.1.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
nameUtils.ts
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (c) 2026-present FERS Contributors (see AUTHORS.md).
3
4import type { PlatformComponent, ScenarioData } from './types';
5
6type ScenarioNameSource = Pick<
7 ScenarioData,
8 'waveforms' | 'timings' | 'antennas' | 'platforms'
9>;
10
11type UniqueNameOptions = {
12 copy?: boolean;
13};
14
15export function getComponentIdentityIds(
16 component: PlatformComponent
17): string[] {
18 return component.type === 'monostatic'
19 ? [component.id, component.txId, component.rxId]
20 : [component.id];
21}
22
23function toIgnoredSet(
24 ignoredIds: Iterable<string | null | undefined> = []
25): Set<string> {
26 const ignored = new Set<string>();
27 for (const id of ignoredIds) {
28 if (id) {
29 ignored.add(id);
30 }
31 }
32 return ignored;
33}
34
35function shouldIgnore(
36 ids: Iterable<string | null | undefined>,
37 ignoredIds: Set<string>
38): boolean {
39 for (const id of ids) {
40 if (id && ignoredIds.has(id)) {
41 return true;
42 }
43 }
44 return false;
45}
46
47export function collectScenarioNames(
48 scenarioData: ScenarioNameSource,
49 ignoredIds: Iterable<string | null | undefined> = []
50): Set<string> {
51 const ignored = toIgnoredSet(ignoredIds);
52 const names = new Set<string>();
53
54 const addName = (
55 name: string,
56 ids: Iterable<string | null | undefined>
57 ) => {
58 if (!shouldIgnore(ids, ignored)) {
59 names.add(name);
60 }
61 };
62
63 for (const waveform of scenarioData.waveforms) {
64 addName(waveform.name, [waveform.id]);
65 }
66 for (const timing of scenarioData.timings) {
67 addName(timing.name, [timing.id]);
68 }
69 for (const antenna of scenarioData.antennas) {
70 addName(antenna.name, [antenna.id]);
71 }
72 for (const platform of scenarioData.platforms) {
73 addName(platform.name, [platform.id]);
74 for (const component of platform.components) {
75 addName(component.name, getComponentIdentityIds(component));
76 }
77 }
78
79 return names;
80}
81
82export function createUniqueName(
83 baseName: string,
84 existingNames: Set<string>,
85 options: UniqueNameOptions = {}
86): string {
87 if (!options.copy && !existingNames.has(baseName)) {
88 return baseName;
89 }
90
91 let candidate = `${baseName} Copy`;
92 let suffix = 2;
93
94 while (existingNames.has(candidate)) {
95 candidate = `${baseName} Copy ${suffix}`;
96 suffix += 1;
97 }
98
99 return candidate;
100}
101
102export function createUniqueScenarioName(
103 scenarioData: ScenarioNameSource,
104 baseName: string,
105 ignoredIds: Iterable<string | null | undefined> = []
106): string {
107 return createUniqueName(
108 baseName,
109 collectScenarioNames(scenarioData, ignoredIds)
110 );
111}
112
113export function createUniqueScenarioCopyName(
114 scenarioData: ScenarioNameSource,
115 baseName: string,
116 ignoredIds: Iterable<string | null | undefined> = []
117): string {
118 return createUniqueName(
119 baseName,
120 collectScenarioNames(scenarioData, ignoredIds),
121 { copy: true }
122 );
123}