85 lines
2.9 KiB
ObjectPascal
85 lines
2.9 KiB
ObjectPascal
unit Myc.Data.Types.RTTI;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils,
|
|
System.RTTI,
|
|
Myc.Data.Types;
|
|
|
|
function AsTValue(const Value: TDataType.TValue): TValue;
|
|
|
|
function RttiTypeToDataType(rttiType: TRttiType): TDataType;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.TypInfo,
|
|
System.Math;
|
|
|
|
// Recursively converts a TRttiType to an IDataType.
|
|
function RttiTypeToDataType(rttiType: TRttiType): TDataType;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
// Convert an RTTI type representation to its corresponding IDataType.
|
|
case rttiType.TypeKind of
|
|
tkInteger, tkInt64, tkChar, tkWChar: Result := TDataType.Ordinal;
|
|
tkFloat:
|
|
if (rttiType.Handle = TypeInfo(TDateTime)) then
|
|
Result := TDataType.Timestamp
|
|
else
|
|
Result := TDataType.Float;
|
|
tkString, tkWideString, tkUString: Result := TDataType.Text;
|
|
tkEnumeration:
|
|
begin
|
|
var enumType := rttiType as TRttiEnumerationType;
|
|
var names := enumType.GetNames;
|
|
var identifiers: TArray<string>;
|
|
SetLength(identifiers, Length(names));
|
|
for i := 0 to High(names) do
|
|
identifiers[i] := names[i];
|
|
Result := TDataType.EnumOf(enumType.Name, identifiers);
|
|
end;
|
|
tkDynArray:
|
|
begin
|
|
var arrayType := rttiType as TRttiDynamicArrayType;
|
|
Result := TDataType.ArrayOf(RttiTypeToDataType(arrayType.ElementType));
|
|
end;
|
|
tkRecord:
|
|
begin
|
|
var recordType := rttiType as TRttiRecordType;
|
|
var fields := recordType.GetFields;
|
|
var recordFields: TArray<TDataRecordField>;
|
|
SetLength(recordFields, Length(fields));
|
|
for i := 0 to High(fields) do
|
|
recordFields[i] := TDataRecordField.Create(fields[i].Name, RttiTypeToDataType(fields[i].FieldType));
|
|
Result := TDataType.RecordOf(recordFields);
|
|
end;
|
|
else
|
|
// Raise an exception for unsupported types.
|
|
raise ENotSupportedException.CreateFmt(
|
|
'Type "%s" (Kind: %s) is not supported for RTTI-based record creation.',
|
|
[rttiType.Name, GetEnumName(TypeInfo(TTypeKind), Ord(rttiType.TypeKind))]);
|
|
end;
|
|
end;
|
|
|
|
{ TValueHelper }
|
|
|
|
function AsTValue(const Value: TDataType.TValue): TValue;
|
|
begin
|
|
case Value.DataType.Kind of
|
|
dkVoid: Result := TValue.Empty;
|
|
dkOrdinal: Result := TValue.From<Int64>(Value.AsOrdinal.Value);
|
|
dkFloat: Result := TValue.From<Double>(Value.AsFloat.Value);
|
|
dkText: Result := TValue.From<string>(Value.AsText.Value);
|
|
dkTimestamp: Result := TValue.From<TDateTime>(Value.AsTimestamp.Value);
|
|
dkEnum: Result := TValue.From<Integer>(Value.AsEnum.Value);
|
|
dkMethod: Result := TValue.From<TDataMethodProc>(Value.AsMethod.Value);
|
|
else
|
|
raise EInvalidOpException.Create('Unsupported data type');
|
|
end;
|
|
end;
|
|
|
|
end.
|