Types-JSON

This commit is contained in:
Michael Schimmel
2025-08-27 18:00:01 +02:00
parent dc4066097c
commit afb8f459c6
7 changed files with 830 additions and 133 deletions
+123 -98
View File
@@ -169,7 +169,13 @@ type
end;
IDataTupleType = interface(IDataType)
{$region 'private'}
function GetItemCount: Integer;
function GetItemType(Idx: Integer): IDataType;
{$endregion}
function CreateValue(const AItems: array of IDataValue): IDataTupleValue;
property ItemCount: Integer read GetItemCount;
property ItemType[Idx: Integer]: IDataType read GetItemType;
end;
IDataArrayValue = interface(IDataValue)
@@ -219,20 +225,6 @@ type
public
constructor Create(const ADataValue: IDataValue);
// Casting
function AsOrdinal: IDataOrdinalValue; inline;
function AsFloat: IDataFloatValue; inline;
function AsText: IDataTextValue; inline;
function AsTimestamp: IDataTimestampValue; inline;
function AsDecimal: IDataDecimalValue; inline;
function AsRecord: IDataRecordValue; inline;
function AsTuple: IDataTupleValue; inline;
function AsArray: IDataArrayValue; inline;
function AsVector: IDataVectorValue; inline;
function AsEnum: IDataEnumValue; inline;
function AsMethod: IDataMethodValue; inline;
function AsVoid: IDataVoidValue; inline;
class operator Implicit(const A: IDataValue): TDataType.TValue; overload; inline;
class operator Implicit(const A: TDataType.TValue): IDataValue; overload; inline;
@@ -466,11 +458,15 @@ type
end;
private
FTupleType: IDataTupleType;
function GetItemCount: Integer; inline;
function GetItemType(Idx: Integer): IDataType; inline;
public
constructor Create(const ATupleType: IDataTupleType);
class operator Implicit(const A: IDataTupleType): TDataType.TTuple; overload; inline;
class operator Implicit(const A: TDataType.TTuple): IDataTupleType; overload; inline;
function CreateValue(const AItems: array of IDataValue): TDataType.TTuple.TValue;
property ItemCount: Integer read GetItemCount;
property ItemType[Idx: Integer]: IDataType read GetItemType;
end;
TArray = record
@@ -560,6 +556,23 @@ type
function CreateValue(const Proc: TProc): TDataType.TMethod.TValue; inline;
end;
// Helper to cast a generic TValue to a specific value helper.
TValueHelper = record helper for TValue
public
function AsVoid: TVoid.TValue; inline;
function AsOrdinal: TOrdinal.TValue; inline;
function AsFloat: TFloat.TValue; inline;
function AsText: TText.TValue; inline;
function AsTimestamp: TTimestamp.TValue; inline;
function AsDecimal: TDecimal.TValue; inline;
function AsRecord: TRecord.TValue; inline;
function AsTuple: TTuple.TValue; inline;
function AsArray: TArray.TValue; inline;
function AsVector: TVector.TValue; inline;
function AsEnum: TEnum.TValue; inline;
function AsMethod: TMethod.TValue; inline;
end;
strict private
FDataType: IDataType;
function GetName: String; inline;
@@ -1247,6 +1260,16 @@ begin
Result.Create(FTupleType.CreateValue(AItems));
end;
function TDataType.TTuple.GetItemCount: Integer;
begin
Result := FTupleType.ItemCount;
end;
function TDataType.TTuple.GetItemType(Idx: Integer): IDataType;
begin
Result := FTupleType.ItemType[Idx];
end;
class operator TDataType.TTuple.Implicit(const A: IDataTupleType): TDataType.TTuple;
begin
Result.FTupleType := A;
@@ -1590,90 +1613,6 @@ begin
FDataValue := ADataValue;
end;
function TDataType.TValue.AsArray: IDataArrayValue;
begin
if (FDataValue.DataType.Kind <> dkArray) then
raise EInvalidCast.Create('Array expected');
Result := IDataArrayValue(FDataValue);
end;
function TDataType.TValue.AsDecimal: IDataDecimalValue;
begin
if (FDataValue.DataType.Kind <> dkDecimal) then
raise EInvalidCast.Create('Decimal expected');
Result := IDataDecimalValue(FDataValue);
end;
function TDataType.TValue.AsEnum: IDataEnumValue;
begin
if (FDataValue.DataType.Kind <> dkEnum) then
raise EInvalidCast.Create('Enum expected');
Result := IDataEnumValue(FDataValue);
end;
function TDataType.TValue.AsFloat: IDataFloatValue;
begin
if (FDataValue.DataType.Kind <> dkFloat) then
raise EInvalidCast.Create('Float expected');
Result := IDataFloatValue(FDataValue);
end;
function TDataType.TValue.AsMethod: IDataMethodValue;
begin
if (FDataValue.DataType.Kind <> dkMethod) then
raise EInvalidCast.Create('Method expected');
Result := IDataMethodValue(FDataValue);
end;
function TDataType.TValue.AsOrdinal: IDataOrdinalValue;
begin
if (FDataValue.DataType.Kind <> dkOrdinal) then
raise EInvalidCast.Create('Ordinal expected');
Result := IDataOrdinalValue(FDataValue);
end;
function TDataType.TValue.AsRecord: IDataRecordValue;
begin
if (FDataValue.DataType.Kind <> dkRecord) then
raise EInvalidCast.Create('Record expected');
Result := IDataRecordValue(FDataValue);
end;
function TDataType.TValue.AsText: IDataTextValue;
begin
if (FDataValue.DataType.Kind <> dkText) then
raise EInvalidCast.Create('Text expected');
Result := IDataTextValue(FDataValue);
end;
function TDataType.TValue.AsTimestamp: IDataTimestampValue;
begin
if (FDataValue.DataType.Kind <> dkTimestamp) then
raise EInvalidCast.Create('Timestamp expected');
Result := IDataTimestampValue(FDataValue);
end;
function TDataType.TValue.AsTuple: IDataTupleValue;
begin
if (FDataValue.DataType.Kind <> dkTuple) then
raise EInvalidCast.Create('Tuple expected');
Result := IDataTupleValue(FDataValue);
end;
function TDataType.TValue.AsVector: IDataVectorValue;
begin
if (FDataValue.DataType.Kind <> dkVector) then
raise EInvalidCast.Create('Vector expected');
Result := IDataVectorValue(FDataValue);
end;
function TDataType.TValue.AsVoid: IDataVoidValue;
begin
if (FDataValue.DataType.Kind <> dkVoid) then
raise EInvalidCast.Create('Void expected');
Result := IDataVoidValue(FDataValue);
end;
function TDataType.TValue.GetDataType: IDataType;
begin
if Assigned(FDataValue) then
@@ -1769,4 +1708,90 @@ begin
Result.Create(IDataVectorType(FDataType));
end;
{ TDataType.TValueHelper }
function TDataType.TValueHelper.AsArray: TDataType.TArray.TValue;
begin
if (FDataValue.DataType.Kind <> dkArray) then
raise EInvalidCast.Create('Array expected');
Result.Create(IDataArrayValue(FDataValue));
end;
function TDataType.TValueHelper.AsDecimal: TDecimal.TValue;
begin
if (FDataValue.DataType.Kind <> dkDecimal) then
raise EInvalidCast.Create('Decimal expected');
Result.Create(IDataDecimalValue(FDataValue));
end;
function TDataType.TValueHelper.AsEnum: TDataType.TEnum.TValue;
begin
if (FDataValue.DataType.Kind <> dkEnum) then
raise EInvalidCast.Create('Enum expected');
Result.Create(IDataEnumValue(FDataValue));
end;
function TDataType.TValueHelper.AsFloat: TDataType.TFloat.TValue;
begin
if (FDataValue.DataType.Kind <> dkFloat) then
raise EInvalidCast.Create('Float expected');
Result.Create(IDataFloatValue(FDataValue));
end;
function TDataType.TValueHelper.AsMethod: TDataType.TMethod.TValue;
begin
if (FDataValue.DataType.Kind <> dkMethod) then
raise EInvalidCast.Create('Method expected');
Result.Create(IDataMethodValue(FDataValue));
end;
function TDataType.TValueHelper.AsOrdinal: TDataType.TOrdinal.TValue;
begin
if (FDataValue.DataType.Kind <> dkOrdinal) then
raise EInvalidCast.Create('Ordinal expected');
Result.Create(IDataOrdinalValue(FDataValue));
end;
function TDataType.TValueHelper.AsRecord: TDataType.TRecord.TValue;
begin
if (FDataValue.DataType.Kind <> dkRecord) then
raise EInvalidCast.Create('Record expected');
Result.Create(IDataRecordValue(FDataValue));
end;
function TDataType.TValueHelper.AsText: TDataType.TText.TValue;
begin
if (FDataValue.DataType.Kind <> dkText) then
raise EInvalidCast.Create('Text expected');
Result.Create(IDataTextValue(FDataValue));
end;
function TDataType.TValueHelper.AsTimestamp: TDataType.TTimestamp.TValue;
begin
if (FDataValue.DataType.Kind <> dkTimestamp) then
raise EInvalidCast.Create('Timestamp expected');
Result.Create(IDataTimestampValue(FDataValue));
end;
function TDataType.TValueHelper.AsTuple: TDataType.TTuple.TValue;
begin
if (FDataValue.DataType.Kind <> dkTuple) then
raise EInvalidCast.Create('Tuple expected');
Result.Create(IDataTupleValue(FDataValue));
end;
function TDataType.TValueHelper.AsVector: TDataType.TVector.TValue;
begin
if (FDataValue.DataType.Kind <> dkVector) then
raise EInvalidCast.Create('Vector expected');
Result.Create(IDataVectorValue(FDataValue));
end;
function TDataType.TValueHelper.AsVoid: TDataType.TVoid.TValue;
begin
if (FDataValue.DataType.Kind <> dkVoid) then
raise EInvalidCast.Create('Void expected');
Result.Create(IDataVoidValue(FDataValue));
end;
end.