unit Myc.Data.Types.Text;

interface

uses
    System.SysUtils,
    Myc.Data.Types;

type
    TImplDataTextType = class(TInterfacedObject, IDataType, IDataTextType)
    strict private
        class var
            FSingleton: IDataTextType;
        class constructor CreateClass;
    public
        function GetName: String;
        function GetKind: TDataKind;
        function CreateValue(const AValue: string): IDataTextValue;
        class property Singleton: IDataTextType read FSingleton;
    end;

implementation

type
    TImplDataTextValue = class(TInterfacedObject, IDataValue, IDataTextValue)
    private
        FValue: string;
        function GetDataType: IDataType;
        function GetAsString: string;
        function GetValue: string;
    public
        constructor Create(const AValue: string);
    end;

    // Singleton implementation for the empty string value.
    TImplDataTextValueEmpty = class(TInterfacedObject, IDataValue, IDataTextValue)
    strict private
        class var
            FSingleton: IDataTextValue;
        class constructor CreateClass;
    private
        function GetDataType: IDataType;
        function GetAsString: string;
        function GetValue: string;
    public
        class property Singleton: IDataTextValue read FSingleton;
    end;

{ TImplDataTextType }

class constructor TImplDataTextType.CreateClass;
begin
    FSingleton := TImplDataTextType.Create;
end;

function TImplDataTextType.CreateValue(const AValue: string): IDataTextValue;
begin
    // Use the singleton for empty strings.
    if (AValue = '') then
        Result := TImplDataTextValueEmpty.Singleton
    else
        Result := TImplDataTextValue.Create(AValue);
end;

function TImplDataTextType.GetName: String;
begin
    Result := 'Text';
end;

function TImplDataTextType.GetKind: TDataKind;
begin
    Result := dkText;
end;

{ TImplDataTextValue }

constructor TImplDataTextValue.Create(const AValue: string);
begin
    inherited Create;
    FValue := AValue;
end;

function TImplDataTextValue.GetDataType: IDataType;
begin
    Result := TImplDataTextType.Singleton;
end;

function TImplDataTextValue.GetAsString: string;
begin
    Result := FValue;
end;

function TImplDataTextValue.GetValue: string;
begin
    Result := FValue;
end;

{ TImplDataTextValueEmpty }

class constructor TImplDataTextValueEmpty.CreateClass;
begin
    FSingleton := TImplDataTextValueEmpty.Create;
end;

function TImplDataTextValueEmpty.GetAsString: string;
begin
    Result := '';
end;

function TImplDataTextValueEmpty.GetDataType: IDataType;
begin
    Result := TImplDataTextType.Singleton;
end;

function TImplDataTextValueEmpty.GetValue: string;
begin
    Result := '';
end;

end.
