-
Notifications
You must be signed in to change notification settings - Fork 2
/
CompositeTypeConverter.ts
91 lines (80 loc) · 2.76 KB
/
CompositeTypeConverter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module TypeConverters
*/
import type { Primitives } from "@itwin/appui-abstract";
import { StandardTypeNames } from "@itwin/appui-abstract";
import { TypeConverter } from "./TypeConverter";
import { TypeConverterManager } from "./TypeConverterManager";
/**
* Composite type converter
* @public
*/
export class CompositeTypeConverter extends TypeConverter {
public override convertToString(
value?: Primitives.Composite
): string | Promise<string> {
if (value === undefined) return "";
return createDisplayValue(value);
}
public sortCompare(
valueA: Primitives.Composite,
valueB: Primitives.Composite,
ignoreCase?: boolean | undefined
): number {
const length = Math.min(valueA.parts.length, valueB.parts.length);
const separatorComparison = compareStrings(
valueA.separator,
valueB.separator,
ignoreCase
);
for (let i = 0; i < length; i++) {
const lhs = valueA.parts[i];
const rhs = valueB.parts[i];
const compareResult =
lhs.typeName !== rhs.typeName
? compareStrings(lhs.displayValue, rhs.displayValue, ignoreCase)
: TypeConverterManager.getConverter(lhs.typeName).sortCompare(
lhs.rawValue,
rhs.rawValue,
ignoreCase
);
if (compareResult !== 0) return compareResult;
if (i === 0 && separatorComparison !== 0) return separatorComparison;
}
if (valueA.parts.length !== valueB.parts.length)
return valueA.parts.length - valueB.parts.length;
return 0;
}
}
TypeConverterManager.registerConverter(
StandardTypeNames.Composite,
CompositeTypeConverter
);
const compareStrings = (lhs: string, rhs: string, ignoreCase?: boolean) => {
if (ignoreCase)
return lhs.toLocaleLowerCase().localeCompare(rhs.toLocaleLowerCase());
else return lhs.localeCompare(rhs);
};
const createDisplayValue = async (
compositeValue: Primitives.Composite
): Promise<string> => {
const parts: string[] = [];
for (const part of compositeValue.parts) {
let valueString: string;
if (part.typeName === "composite") {
valueString = await createDisplayValue(
part.rawValue as Primitives.Composite
);
} else {
valueString = await TypeConverterManager.getConverter(
part.typeName
).convertToString(part.rawValue);
}
parts.push(valueString);
}
return parts.join(compositeValue.separator);
};