Support for GenericStreamingMessage
This commit is contained in:
109
lib/classes/python/PythonDict.ts
Normal file
109
lib/classes/python/PythonDict.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import { PythonTokenContainer } from './PythonTokenContainer';
|
||||
import { PythonObject } from './PythonObject';
|
||||
import { PythonTokenType } from './PythonTokenType';
|
||||
import { PythonType } from './PythonType';
|
||||
import { PythonParser } from './PythonParser';
|
||||
import { PythonTuple } from './PythonTuple';
|
||||
|
||||
// Define PythonKey type for dictionary keys
|
||||
export type PythonKey = string | boolean | PythonType[] | number | PythonTuple;
|
||||
|
||||
export class PythonDict extends PythonObject
|
||||
{
|
||||
public data: Map<PythonKey, PythonType> = new Map<PythonKey, PythonType>();
|
||||
|
||||
public static parse(container: PythonTokenContainer): PythonDict
|
||||
{
|
||||
const dict = new PythonDict();
|
||||
|
||||
let isKey = true;
|
||||
let key: PythonKey | null = null;
|
||||
|
||||
while (container.index < container.tokens.length)
|
||||
{
|
||||
const token = container.tokens[container.index];
|
||||
|
||||
switch (token.type)
|
||||
{
|
||||
case PythonTokenType.BRACE_END:
|
||||
{
|
||||
if (isKey)
|
||||
{
|
||||
// The last token is a key, which is invalid
|
||||
throw new Error('Unexpected end of dictionary: Expected a key-value pair.');
|
||||
}
|
||||
|
||||
container.index++;
|
||||
return dict;
|
||||
}
|
||||
case PythonTokenType.COLON:
|
||||
{
|
||||
if (!isKey)
|
||||
{
|
||||
throw new Error('Expected a key before the colon in a dictionary.');
|
||||
}
|
||||
isKey = false;
|
||||
container.index++;
|
||||
break;
|
||||
}
|
||||
case PythonTokenType.COMMA:
|
||||
{
|
||||
if (isKey)
|
||||
{
|
||||
throw new Error('No value provided with dictionary key');
|
||||
}
|
||||
isKey = true;
|
||||
container.index++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (isKey)
|
||||
{
|
||||
// Parse the key and check its type
|
||||
key = PythonParser.parseValueToken(container) as PythonKey;
|
||||
|
||||
if (
|
||||
typeof key !== 'string' &&
|
||||
typeof key !== 'number' &&
|
||||
typeof key !== 'boolean' &&
|
||||
!(key instanceof PythonTuple) && // Check if it's a PythonTuple
|
||||
typeof key !== 'object' // Allow floats
|
||||
)
|
||||
{
|
||||
throw new Error('Invalid key type in a dictionary.');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parse the value
|
||||
if (key === null)
|
||||
{
|
||||
throw new Error('Key cannot be null in a dictionary.');
|
||||
}
|
||||
const value = PythonParser.parseValueToken(container);
|
||||
dict.data.set(key, value);
|
||||
key = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Expected close brace } in dictionary');
|
||||
}
|
||||
|
||||
get length(): number
|
||||
{
|
||||
return Object.keys(this.data).length;
|
||||
}
|
||||
|
||||
public get(key: PythonKey): PythonType | undefined
|
||||
{
|
||||
return this.data.get(key);
|
||||
}
|
||||
|
||||
public toJSON(): unknown
|
||||
{
|
||||
return Object.fromEntries(this.data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user