/** * Helper functions for working with service types */ import type { ServiceListFilterDefinition } from '@/types/service'; import { ListFilterComparisonOperator } from '@/types/common'; /** * Parse a filter specification string into its components * * @param spec - Filter specification string (e.g., "s:200:256:771") * @returns Parsed filter specification object * * @example * parseFilterSpec("s:200:256:771") * // Returns: { * // type: 'string', * // length: 200, * // defaultComparator: 256 (LIKE), * // supportedComparators: [1, 2, 256, 512] (EQ, NEQ, LIKE, NLIKE) * // } */ export function parseFilterSpec(spec: string): ServiceListFilterDefinition { const [typeCode, lengthStr, defaultComparatorStr, supportedComparatorsStr] = spec.split(':'); const typeMap: Record = { 's': 'string', 'i': 'integer', 'd': 'date', 'b': 'boolean', 'a': 'array', }; const type = typeMap[typeCode]; if (!type) { throw new Error(`Invalid filter type code: ${typeCode}`); } const length = parseInt(lengthStr, 10); const defaultComparator = parseInt(defaultComparatorStr, 10) as ListFilterComparisonOperator; // Parse supported comparators from bitmask const supportedComparators: ListFilterComparisonOperator[] = []; const supportedBitmask = parseInt(supportedComparatorsStr, 10); if (supportedBitmask !== 0) { const allComparators = Object.values(ListFilterComparisonOperator).filter(v => typeof v === 'number') as number[]; for (const comparator of allComparators) { if ((supportedBitmask & comparator) === comparator) { supportedComparators.push(comparator as ListFilterComparisonOperator); } } } return { type, length, defaultComparator, supportedComparators, }; }