Skip to content

Commit

Permalink
Now you can pass a string to the NeonFormatAttribute so the format ca…
Browse files Browse the repository at this point in the history
…n be extensible

Use of the NeonFormat enum is now deprecated
  • Loading branch information
paolo-rossi committed May 2, 2024
1 parent 6ec48ef commit deba0b2
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 20 deletions.
19 changes: 16 additions & 3 deletions Source/Neon.Core.Attributes.pas
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,13 @@ NeonIncludeAttribute = class(TCustomAttribute)
/// Currently Base64 is supported for TBytes through a CustomSerializer
/// </remarks>
NeonFormat = (Native, Base64);
NeonFormatAttribute = class(NeonAttribute)
NeonFormatAttribute = class(NeonNamedAttribute)
private
FFormatValue: NeonFormat;
public
constructor Create(AOutputValue: NeonFormat = NeonFormat.Native);
constructor Create(AOutputValue: NeonFormat = NeonFormat.Native); overload; deprecated;
constructor Create(AOutputValue: string = 'native'); overload;
function IsValue(const AValue: string): Boolean;
property FormatValue: NeonFormat read FFormatValue write FFormatValue;
end;

Expand Down Expand Up @@ -291,7 +293,7 @@ NeonAnyGetterAttribute = class(NeonAttribute);
implementation

uses
System.StrUtils, System.DateUtils;
System.StrUtils, System.TypInfo, System.DateUtils;

{ NeonNamedAttribute }

Expand Down Expand Up @@ -345,6 +347,17 @@ constructor NeonEnumNamesAttribute.Create(const ANames: string);
constructor NeonFormatAttribute.Create(AOutputValue: NeonFormat);
begin
FFormatValue := AOutputValue;
FValue := LowerCase(GetEnumName(TypeInfo(NeonFormat), Integer(AOutputValue)));
end;

constructor NeonFormatAttribute.Create(AOutputValue: string);
begin
FValue := AOutputValue;
end;

function NeonFormatAttribute.IsValue(const AValue: string): Boolean;
begin
Result := SameText(FValue, AValue);
end;

{ NeonItemFactoryAttribute }
Expand Down
50 changes: 34 additions & 16 deletions Source/Neon.Core.Serializers.RTL.pas
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ TTValueSerializer = class(TCustomSerializer)
/// Base64 using NeonFormat attribute
/// </summary>
TBytesSerializer = class(TCustomSerializer)
private
function IsFormatValue(AFormat: NeonFormatAttribute; const AValue: string): Boolean; inline;

function ValueAsBase64(const AValue: TJSONValue): TValue; inline;
protected
class function GetTargetInfo: PTypeInfo; override;
class function CanHandle(AType: PTypeInfo): Boolean; override;
Expand Down Expand Up @@ -332,25 +336,26 @@ class function TBytesSerializer.CanHandle(AType: PTypeInfo): Boolean;
function TBytesSerializer.Deserialize(AValue: TJSONValue; const AData: TValue;
ANeonObject: TNeonRttiObject; AContext: IDeserializerContext): TValue;
var
LVal: TBytes;
LType: TRttiType;
LFormat: NeonFormatAttribute;
begin
LFormat := ANeonObject.GetAttribute<NeonFormatAttribute>;
if Assigned(LFormat) and (LFormat.FormatValue = NeonFormat.Native) then
if IsFormatValue(LFormat, 'native') then
begin
LType := TRttiUtils.Context.GetType(TypeInfo(TBytes));
Result := AContext.ReadDataMember(AValue, LType, AData, False);
end
else
begin
if (AValue is TJSONString) then
LVal := TBase64.Decode(AValue.Value)
else
raise ENeonException.Create('JSONValue must be a string');

Result := TValue.From<TBytes>(LVal);
Exit(AContext.ReadDataMember(AValue, LType, AData, False));
end;

//if IsFormatValue(LFormat, 'base64') then
Result := ValueAsBase64(AValue);
end;

function TBytesSerializer.IsFormatValue(AFormat: NeonFormatAttribute; const AValue: string): Boolean;
begin
if not Assigned(AFormat) then
Exit(False);

Result := AFormat.IsValue(AValue);
end;

class function TBytesSerializer.GetTargetInfo: PTypeInfo;
Expand All @@ -366,10 +371,23 @@ function TBytesSerializer.Serialize(const AValue: TValue;
begin
LVal := AValue.AsType<TBytes>;
LFormat := ANeonObject.GetAttribute<NeonFormatAttribute>;
if Assigned(LFormat) and (LFormat.FormatValue = NeonFormat.Native) then
Result := AContext.WriteDataMember(AValue, False)
else
Result := TJSONString.Create(TBase64.Encode(LVal));

if IsFormatValue(LFormat, 'native') then
Exit(AContext.WriteDataMember(AValue, False));

//if IsFormatValue(LFormat, 'base64') then
Exit(TJSONString.Create(TBase64.Encode(LVal)));
end;

function TBytesSerializer.ValueAsBase64(const AValue: TJSONValue): TValue;
var
LVal: TBytes;
begin
if not (AValue is TJSONString) then
raise ENeonException.Create('JSONValue must be a string');

LVal := TBase64.Decode(AValue.Value);
Result := TValue.From<TBytes>(LVal);
end;

end.
2 changes: 1 addition & 1 deletion Tests/Source/Neon.Tests.Entities.pas
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ interface

TBytes64Rec = record
Bytes: TBytes;
[NeonFormat(NeonFormat.Native)]
[NeonFormat('native')]
ByteArray: TBytes;
end;

Expand Down

0 comments on commit deba0b2

Please sign in to comment.