mirror of
https://github.com/home-assistant/frontend.git
synced 2025-10-07 02:39:40 +00:00
121 lines
2.5 KiB
TypeScript
121 lines
2.5 KiB
TypeScript
import memoizeOne from "memoize-one";
|
|
import { isIPAddress } from "./is_ip_address";
|
|
|
|
const collator = memoizeOne(
|
|
(language: string | undefined) =>
|
|
new Intl.Collator(language, { numeric: true })
|
|
);
|
|
|
|
const caseInsensitiveCollator = memoizeOne(
|
|
(language: string | undefined) =>
|
|
new Intl.Collator(language, { sensitivity: "accent", numeric: true })
|
|
);
|
|
|
|
const fallbackStringCompare = (a: string, b: string) => {
|
|
if (a < b) {
|
|
return -1;
|
|
}
|
|
if (a > b) {
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
|
|
export const stringCompare = (
|
|
a: string,
|
|
b: string,
|
|
language: string | undefined = undefined
|
|
) => {
|
|
// @ts-ignore
|
|
if (Intl?.Collator) {
|
|
return collator(language).compare(a, b);
|
|
}
|
|
|
|
return fallbackStringCompare(a, b);
|
|
};
|
|
|
|
export const ipCompare = (a: string, b: string) => {
|
|
const aIsIpV4 = isIPAddress(a);
|
|
const bIsIpV4 = isIPAddress(b);
|
|
|
|
if (aIsIpV4 && bIsIpV4) {
|
|
return ipv4Compare(a, b);
|
|
}
|
|
if (!aIsIpV4 && !bIsIpV4) {
|
|
return ipV6Compare(a, b);
|
|
}
|
|
return aIsIpV4 ? -1 : 1;
|
|
};
|
|
|
|
export const caseInsensitiveStringCompare = (
|
|
a: string,
|
|
b: string,
|
|
language: string | undefined = undefined
|
|
) => {
|
|
// @ts-ignore
|
|
if (Intl?.Collator) {
|
|
return caseInsensitiveCollator(language).compare(a, b);
|
|
}
|
|
|
|
return fallbackStringCompare(a.toLowerCase(), b.toLowerCase());
|
|
};
|
|
|
|
export const orderCompare = (order: string[]) => (a: string, b: string) => {
|
|
const idxA = order.indexOf(a);
|
|
const idxB = order.indexOf(b);
|
|
|
|
if (idxA === idxB) {
|
|
return 0;
|
|
}
|
|
|
|
if (idxA === -1) {
|
|
return 1;
|
|
}
|
|
|
|
if (idxB === -1) {
|
|
return -1;
|
|
}
|
|
|
|
return idxA - idxB;
|
|
};
|
|
|
|
function ipv4Compare(a: string, b: string) {
|
|
const num1 = Number(
|
|
a
|
|
.split(".")
|
|
.map((num) => num.padStart(3, "0"))
|
|
.join("")
|
|
);
|
|
const num2 = Number(
|
|
b
|
|
.split(".")
|
|
.map((num) => num.padStart(3, "0"))
|
|
.join("")
|
|
);
|
|
return num1 - num2;
|
|
}
|
|
|
|
function ipV6Compare(a: string, b: string) {
|
|
const ipv6a = normalizeIPv6(a)
|
|
.split(":")
|
|
.map((part) => part.padStart(4, "0"))
|
|
.join("");
|
|
const ipv6b = normalizeIPv6(b)
|
|
.split(":")
|
|
.map((part) => part.padStart(4, "0"))
|
|
.join("");
|
|
|
|
return ipv6a.localeCompare(ipv6b);
|
|
}
|
|
|
|
function normalizeIPv6(ip) {
|
|
const parts = ip.split("::");
|
|
const head = parts[0].split(":");
|
|
const tail = parts[1] ? parts[1].split(":") : [];
|
|
const totalParts = 8;
|
|
const missing = totalParts - (head.length + tail.length);
|
|
const zeros = new Array(missing).fill("0");
|
|
return [...head, ...zeros, ...tail].join(":");
|
|
}
|