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; 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; 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(Value.AsOrdinal.Value); dkFloat: Result := TValue.From(Value.AsFloat.Value); dkText: Result := TValue.From(Value.AsText.Value); dkTimestamp: Result := TValue.From(Value.AsTimestamp.Value); dkEnum: Result := TValue.From(Value.AsEnum.Value); dkMethod: Result := TValue.From(Value.AsMethod.Value); else raise EInvalidOpException.Create('Unsupported data type'); end; end; end.