• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import {assertTrue} from './assert_utils';
17
18/**
19 * String utility functions.
20 */
21export class StringUtils {
22  static parseBigIntStrippingUnit(s: string): bigint {
23    const match = s.match(/^\s*(-?\d+)\D*.*$/);
24    if (!match) {
25      throw new Error(`Cannot parse '${s}' as bigint`);
26    }
27    return BigInt(match[1]);
28  }
29
30  static convertCamelToSnakeCase(s: string): string {
31    const result: string[] = [];
32
33    let prevChar: string | undefined;
34    for (const currChar of s) {
35      const prevCharCouldBeWordEnd =
36        prevChar &&
37        (StringUtils.isDigit(prevChar) || StringUtils.isLowerCase(prevChar));
38      const currCharCouldBeWordStart = StringUtils.isUpperCase(currChar);
39      if (prevCharCouldBeWordEnd && currCharCouldBeWordStart) {
40        result.push('_');
41        result.push(currChar.toLowerCase());
42      } else {
43        result.push(currChar);
44      }
45      prevChar = currChar;
46    }
47
48    return result.join('');
49  }
50
51  static convertSnakeToCamelCase(s: string): string {
52    const tokens = s.split('_').filter((token) => token.length > 0);
53    const tokensCapitalized = tokens.map((token) => {
54      return StringUtils.capitalizeFirstCharIfAlpha(token);
55    });
56
57    const inputStartsWithUnderscore = s[0] === '_';
58    let result = inputStartsWithUnderscore ? '_' : '';
59    result += tokens[0];
60    for (const token of tokensCapitalized.slice(1)) {
61      if (!StringUtils.isAlpha(token[0])) {
62        result += '_';
63      }
64      result += token;
65    }
66
67    return result;
68  }
69
70  static isAlpha(char: string): boolean {
71    assertTrue(char.length === 1, () => 'Input must be a single character');
72    return char[0].toLowerCase() !== char[0].toUpperCase();
73  }
74
75  static isDigit(char: string): boolean {
76    assertTrue(char.length === 1, () => 'Input must be a single character');
77    return char >= '0' && char <= '9';
78  }
79
80  static isLowerCase(char: string): boolean {
81    assertTrue(char.length === 1, () => 'Input must be a single character');
82    return StringUtils.isAlpha(char) && char === char.toLowerCase();
83  }
84
85  static isUpperCase(char: string): boolean {
86    assertTrue(char.length === 1, () => 'Input must be a single character');
87    return StringUtils.isAlpha(char) && char === char.toUpperCase();
88  }
89
90  static isBlank(str: string): boolean {
91    return str.replace(/\s/g, '').length === 0;
92  }
93
94  static isNumeric(str: string): boolean {
95    return Number(str).toString() === str;
96  }
97
98  private static capitalizeFirstCharIfAlpha(word: string): string {
99    if (word.length === 0) {
100      return word;
101    }
102
103    if (!StringUtils.isAlpha(word[0])) {
104      return word;
105    }
106    return word[0].toUpperCase() + word.slice(1);
107  }
108}
109