Skip to content

Instantly share code, notes, and snippets.

@themarwhal
Created May 17, 2022 00:22
Show Gist options
  • Save themarwhal/3895dee3d912c324451ff061d5341b06 to your computer and use it in GitHub Desktop.
Save themarwhal/3895dee3d912c324451ff061d5341b06 to your computer and use it in GitHub Desktop.
enum ValueType {
ARRAY,
INFO_OBJECT,
OBJECT,
RAW,
}
function splitOnTopLevelProviders(data: string): Map<string, string> {
let result = new Map<string, string>();
// Each array element looks like "target1: Providers(...)"
let providers = data.trim().split('\n\n');
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
let firstProvidersIndex = provider.indexOf('Providers');
result.set(
provider.slice(0, firstProvidersIndex).trim(),
provider.slice(firstProvidersIndex, provider.length).trim(),
);
}
// result should look like
// {'target1:' : 'Providers(...)', 'target2:' : 'Providers(...)'}
return result;
}
function processComma(char: string): 1 | -1 | 0 {
if (char === '(' || char === '[' || char === '{') {
return 1;
} else if (char === ')' || char === ']' || char === '}') {
return -1;
}
return 0;
}
function splitStringByIndices(data: string, indicies: number[]): string[] {
let result = [] as string[];
let prevIndex = 0;
for (let i = 0; i < indicies.length; i++) {
let commaIndex = indicies[i];
result.push(data.slice(prevIndex, commaIndex).trim());
prevIndex = commaIndex + 1;
}
result.push(data.slice(prevIndex, data.length));
return result;
}
function splitOnTopLevelComma(data: string): string[] {
let topLevelCommaIndicies = [] as number[];
let counter = 0;
for (let i = 0; i < data.length; i++) {
let char = data[i];
counter = counter + processComma(char);
if (char === ',' && counter === 0) {
topLevelCommaIndicies.push(i);
}
}
return splitStringByIndices(data, topLevelCommaIndicies);
}
function getTopLevelDataType(data: string): ValueType {
// Look at the last character to figure out object type
let lastChar = data[data.length - 1];
let firstChar = data[0];
if (lastChar === ']') {
return ValueType.ARRAY;
} else if (lastChar === ')') {
return ValueType.INFO_OBJECT;
} else if (firstChar === '{' && lastChar === '}') {
return ValueType.OBJECT;
}
return ValueType.RAW;
}
function parseKeyFromInfoObjectString(data: string): [string, string] {
let openIndex = data.indexOf('(');
return [data.slice(0, openIndex), data.slice(openIndex + 1, data.length - 1)];
}
function parseProvider(data: string): any {
let type = getTopLevelDataType(data);
if (type == ValueType.RAW) {
return data;
}
if (type == ValueType.INFO_OBJECT) {
let result = new Map<string, any>();
let [keyName, rawVal] = parseKeyFromInfoObjectString(data);
if (keyName == 'Providers') {
result.set(keyName, parseProvider(rawVal));
return result;
}
let splitRawVal = splitOnTopLevelComma(rawVal);
let object = new Map<string, any>();
for (let i = 0; i < splitRawVal.length; i++) {
let splitOnEqual = splitRawVal[i].split('=');
object.set(splitOnEqual[0], parseProvider(splitOnEqual[1]));
}
result.set(keyName, object);
return result;
}
if (type == ValueType.OBJECT) {
if (data === '{}') {
return {};
}
let rawVal = data.slice(1, data.length - 1);
let object = new Map<string, any>();
let splitRawVal = splitOnTopLevelComma(rawVal);
for (let i = 0; i < splitRawVal.length; i++) {
let splitOnEqual = splitRawVal[i].split(': ');
object.set(splitOnEqual[0], parseProvider(splitOnEqual[1]));
}
let result = new Map<string, any>();
result.set('object', object);
return result;
}
if (type == ValueType.ARRAY) {
let rawVal = data.slice(1, data.length - 1);
let splitRawVal = splitOnTopLevelComma(rawVal);
return splitRawVal.map((value: string) => {
return parseProvider(value);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment