Skip to content

Commit

Permalink
imp - Unify building arguments
Browse files Browse the repository at this point in the history
---

We've managed to unify the argument builder. Now, we don't have to depend on parts to build arguments themselves. We'll leave this task to VisualCard instead.

---

Type: imp
Breaking: False
Doc Required: False
Part: 1/1
  • Loading branch information
AptiviCEO committed Mar 31, 2024
1 parent ba9c48e commit c1644ef
Show file tree
Hide file tree
Showing 29 changed files with 189 additions and 498 deletions.
1 change: 1 addition & 0 deletions VisualCard/Parsers/VcardConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ internal static class VcardConstants
internal const char _fieldDelimiter = ';';
internal const char _valueDelimiter = ',';
internal const char _argumentDelimiter = ':';
internal const char _argumentValueDelimiter = '=';
internal const string _nameSpecifier = "N";
internal const string _fullNameSpecifier = "FN";
internal const string _telephoneSpecifier = "TEL";
Expand Down
7 changes: 2 additions & 5 deletions VisualCard/Parsers/VcardParserTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,8 @@ internal static string GetTypesString(string[] args, string @default, bool isSpe
// Attempt to get the value from the key
Type =
ArgType.Count() > 0 ?
ArgType[0].StartsWith(VcardConstants._typeArgumentSpecifier) ?
string.Join(VcardConstants._valueDelimiter.ToString(), ArgType.Select((arg) => arg.Substring(VcardConstants._typeArgumentSpecifier.Length))) :
ArgType[0]
:
@default;
string.Join(VcardConstants._valueDelimiter.ToString(), ArgType.Select((arg) => arg.StartsWith(VcardConstants._typeArgumentSpecifier) ? arg.Substring(VcardConstants._typeArgumentSpecifier.Length) : arg)) :
@default;

// Return the type
return Type;
Expand Down
2 changes: 1 addition & 1 deletion VisualCard/Parts/BaseCardPartInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace VisualCard.Parts
/// <summary>
/// Base card part class
/// </summary>
[DebuggerDisplay("Base card part | ALTID: {AltId}, TYPE: {ElementType}, VALUE: {ValueType}")]
[DebuggerDisplay("Base card part | ALTID: {AltId}, TYPE: {ElementTypes}, VALUE: {ValueType}")]
public abstract class BaseCardPartInfo : IEquatable<BaseCardPartInfo>
{
/// <summary>
Expand Down
29 changes: 26 additions & 3 deletions VisualCard/Parts/Card.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using System.Diagnostics;
using System.IO;
using System.Text;
using Textify.General;
using VisualCard.Parsers;
using VisualCard.Parts.Comparers;
using VisualCard.Parts.Enums;
Expand Down Expand Up @@ -144,7 +145,7 @@ public string SaveToString()

// Now, locate the prefix and assemble the line
string prefix = VcardParserTools.GetPrefixFromStringsEnum(stringEnum);
cardBuilder.AppendLine($"{prefix}:{stringValue}");
cardBuilder.AppendLine($"{prefix}{VcardConstants._argumentDelimiter}{stringValue}");
}

// Next, enumerate all the arrays
Expand All @@ -156,9 +157,21 @@ public string SaveToString()
if (array is null || array.Length == 0)
continue;

// Get the prefix
string prefix = VcardParserTools.GetPrefixFromPartsArrayEnum(partsArrayEnum);

// Now, assemble the line
foreach (var part in array)
cardBuilder.AppendLine($"{part.ToStringVcardInternal(version)}");
{
var partBuilder = new StringBuilder();
string partRepresentation = part.ToStringVcardInternal(version);
string partArguments = CardBuilderTools.BuildArguments(part, version);
string[] partArgumentsLines = partArguments.SplitNewLines();
partBuilder.Append($"{prefix}");
partBuilder.Append($"{partArguments}");
partBuilder.Append($"{VcardParserTools.MakeStringBlock(partRepresentation, partArgumentsLines[partArgumentsLines.Length - 1].Length + prefix.Length)}");
cardBuilder.AppendLine($"{partBuilder}");
}
}

// Finally, enumerate all the parts
Expand All @@ -170,8 +183,18 @@ public string SaveToString()
if (part is null)
continue;

// Get the prefix
string prefix = VcardParserTools.GetPrefixFromPartsEnum(partsEnum);

// Now, assemble the line
cardBuilder.AppendLine($"{part.ToStringVcardInternal(version)}");
var partBuilder = new StringBuilder();
string partRepresentation = part.ToStringVcardInternal(version);
string partArguments = CardBuilderTools.BuildArguments(part, version);
string[] partArgumentsLines = partArguments.SplitNewLines();
partBuilder.Append($"{prefix}");
partBuilder.Append($"{partArguments}");
partBuilder.Append($"{VcardParserTools.MakeStringBlock(partRepresentation, partArgumentsLines[partArgumentsLines.Length - 1].Length + prefix.Length)}");
cardBuilder.AppendLine($"{partBuilder}");
}

// End the card and return it
Expand Down
100 changes: 100 additions & 0 deletions VisualCard/Parts/CardBuilderTools.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// VisualCard Copyright (C) 2021-2024 Aptivi
//
// This file is part of VisualCard
//
// VisualCard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// VisualCard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY, without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VisualCard.Parsers;
using VisualCard.Parts.Implementations;

namespace VisualCard.Parts
{
internal static class CardBuilderTools
{
internal static string BuildArguments(BaseCardPartInfo partInfo, Version cardVersion)
{
// Check to see if we've been provided arguments
bool installAltId = partInfo.AltId >= 0 && partInfo.Arguments.Length > 0 && cardVersion.Major >= 4;
bool noSemicolon = partInfo.AltId == 0 && partInfo.Arguments.Length == 0 && partInfo.ElementTypes.Length == 0 && string.IsNullOrEmpty(partInfo.ValueType);
string xNonstandardName = partInfo is XNameInfo xName ? xName.XKeyName : "";
if (noSemicolon)
return xNonstandardName + VcardConstants._argumentDelimiter.ToString();

// Now, initialize the argument builder
StringBuilder argumentsBuilder = new(xNonstandardName + VcardConstants._fieldDelimiter.ToString());
bool installArguments = partInfo.Arguments.Length > 0;
bool installElementTypes = partInfo.ElementTypes.Length > 0;
bool installValueType = !string.IsNullOrEmpty(partInfo.ValueType);

// First, install the AltId parameter if it exists
if (installAltId)
{
argumentsBuilder.Append(VcardConstants._altIdArgumentSpecifier + partInfo.AltId);
noSemicolon = !installArguments && !installElementTypes && !installValueType;
if (noSemicolon)
{
argumentsBuilder.Append(VcardConstants._argumentDelimiter.ToString());
return argumentsBuilder.ToString();
}
else
argumentsBuilder.Append(VcardConstants._fieldDelimiter.ToString());
}

// Then, install the element types parameter if it exists
if (installElementTypes)
{
argumentsBuilder.Append(VcardConstants._typeArgumentSpecifier + string.Join(",", partInfo.ElementTypes));
noSemicolon = !installArguments && !installValueType;
if (noSemicolon)
{
argumentsBuilder.Append(VcardConstants._argumentDelimiter.ToString());
return argumentsBuilder.ToString();
}
else
argumentsBuilder.Append(VcardConstants._fieldDelimiter.ToString());
}

// Then, install the value type parameter if it exists
if (installValueType)
{
argumentsBuilder.Append(VcardConstants._valueArgumentSpecifier + string.Join(",", partInfo.ValueType));
noSemicolon = !installArguments;
if (noSemicolon)
{
argumentsBuilder.Append(VcardConstants._argumentDelimiter.ToString());
return argumentsBuilder.ToString();
}
else
argumentsBuilder.Append(VcardConstants._fieldDelimiter.ToString());
}

// Finally, install the remaining arguments if they exist and contain keys and values
if (installArguments)
{
string[] finalArguments = partInfo.Arguments.Where((arg) => arg.Contains(VcardConstants._argumentValueDelimiter)).ToArray();
argumentsBuilder.Append(string.Join(VcardConstants._fieldDelimiter.ToString(), finalArguments));
}

// We've reached the end.
argumentsBuilder.Append(VcardConstants._argumentDelimiter.ToString());
return argumentsBuilder.ToString();
}
}
}
40 changes: 8 additions & 32 deletions VisualCard/Parts/Implementations/AddressInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,38 +64,14 @@ public class AddressInfo : BaseCardPartInfo, IEquatable<AddressInfo>
internal static BaseCardPartInfo FromStringVcardStatic(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion) =>
new AddressInfo().FromStringVcardInternal(value, finalArgs, altId, elementTypes, valueType, cardVersion);

internal override string ToStringVcardInternal(Version cardVersion)
{
bool altIdSupported = cardVersion.Major >= 4;
if (altIdSupported)
{
bool installAltId = AltId >= 0 && Arguments.Length > 0;
return
$"{VcardConstants._addressSpecifier};" +
$"{(installAltId ? VcardConstants._altIdArgumentSpecifier + AltId + VcardConstants._fieldDelimiter : "")}" +
$"{VcardConstants._typeArgumentSpecifier}{string.Join(",", ElementTypes)}{VcardConstants._argumentDelimiter}" +
$"{PostOfficeBox}{VcardConstants._fieldDelimiter}" +
$"{ExtendedAddress}{VcardConstants._fieldDelimiter}" +
$"{StreetAddress}{VcardConstants._fieldDelimiter}" +
$"{Locality}{VcardConstants._fieldDelimiter}" +
$"{Region}{VcardConstants._fieldDelimiter}" +
$"{PostalCode}{VcardConstants._fieldDelimiter}" +
$"{Country}";
}
else
{
return
$"{VcardConstants._addressSpecifier};" +
$"{VcardConstants._typeArgumentSpecifier}{string.Join(",", ElementTypes)}{VcardConstants._argumentDelimiter}" +
$"{PostOfficeBox}{VcardConstants._fieldDelimiter}" +
$"{ExtendedAddress}{VcardConstants._fieldDelimiter}" +
$"{StreetAddress}{VcardConstants._fieldDelimiter}" +
$"{Locality}{VcardConstants._fieldDelimiter}" +
$"{Region}{VcardConstants._fieldDelimiter}" +
$"{PostalCode}{VcardConstants._fieldDelimiter}" +
$"{Country}";
}
}
internal override string ToStringVcardInternal(Version cardVersion) =>
$"{PostOfficeBox}{VcardConstants._fieldDelimiter}" +
$"{ExtendedAddress}{VcardConstants._fieldDelimiter}" +
$"{StreetAddress}{VcardConstants._fieldDelimiter}" +
$"{Locality}{VcardConstants._fieldDelimiter}" +
$"{Region}{VcardConstants._fieldDelimiter}" +
$"{PostalCode}{VcardConstants._fieldDelimiter}" +
$"{Country}";

internal override BaseCardPartInfo FromStringVcardInternal(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion)
{
Expand Down
21 changes: 3 additions & 18 deletions VisualCard/Parts/Implementations/AgentInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,12 @@ internal static BaseCardPartInfo FromStringVcardStatic(string value, string[] fi
internal override string ToStringVcardInternal(Version cardVersion)
{
var agents = new StringBuilder();
bool altIdSupported = cardVersion.Major >= 4;

foreach (var a in AgentCards)
{
if (altIdSupported)
{
bool installAltId = AltId >= 0 && Arguments.Length > 0;
agents.Append(
$"{VcardConstants._agentSpecifier}" +
$"{(installAltId ? $"{VcardConstants._fieldDelimiter}{VcardConstants._altIdArgumentSpecifier}" + AltId : "")}" +
$"{VcardConstants._argumentDelimiter}" +
$"{string.Join("\\n", a.SaveToString().SplitNewLines())}"
);
}
else
{
agents.Append(
$"{VcardConstants._agentSpecifier}{VcardConstants._argumentDelimiter}" +
$"{string.Join("\\n", a.SaveToString().SplitNewLines())}"
);
}
agents.Append(
$"{string.Join("\\n", a.SaveToString().SplitNewLines())}"
);
}
return agents.ToString();
}
Expand Down
2 changes: 1 addition & 1 deletion VisualCard/Parts/Implementations/AnniversaryInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal static BaseCardPartInfo FromStringVcardStatic(string value, string[] fi
new AnniversaryInfo().FromStringVcardInternal(value, finalArgs, altId, elementTypes, valueType, cardVersion);

internal override string ToStringVcardInternal(Version cardVersion) =>
$"{VcardConstants._anniversarySpecifier}:{Anniversary:yyyyMMdd}";
$"{Anniversary:yyyyMMdd}";

internal override BaseCardPartInfo FromStringVcardInternal(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion)
{
Expand Down
2 changes: 1 addition & 1 deletion VisualCard/Parts/Implementations/BirthDateInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal static BaseCardPartInfo FromStringVcardStatic(string value, string[] fi
new BirthDateInfo().FromStringVcardInternal(value, finalArgs, altId, elementTypes, valueType, cardVersion);

internal override string ToStringVcardInternal(Version cardVersion) =>
$"{VcardConstants._birthSpecifier}:{BirthDate:yyyyMMdd}";
$"{BirthDate:yyyyMMdd}";

internal override BaseCardPartInfo FromStringVcardInternal(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion)
{
Expand Down
8 changes: 2 additions & 6 deletions VisualCard/Parts/Implementations/CategoryInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,8 @@ public class CategoryInfo : BaseCardPartInfo, IEquatable<CategoryInfo>
internal static BaseCardPartInfo FromStringVcardStatic(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion) =>
new CategoryInfo().FromStringVcardInternal(value, finalArgs, altId, elementTypes, valueType, cardVersion);

internal override string ToStringVcardInternal(Version cardVersion)
{
return
$"{VcardConstants._categoriesSpecifier}:" +
$"{Category}";
}
internal override string ToStringVcardInternal(Version cardVersion) =>
$"{string.Join(VcardConstants._valueDelimiter.ToString(), Category)}";

internal override BaseCardPartInfo FromStringVcardInternal(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion)
{
Expand Down
22 changes: 2 additions & 20 deletions VisualCard/Parts/Implementations/EmailInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,8 @@ public class EmailInfo : BaseCardPartInfo, IEquatable<EmailInfo>
internal static BaseCardPartInfo FromStringVcardStatic(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion) =>
new EmailInfo().FromStringVcardInternal(value, finalArgs, altId, elementTypes, valueType, cardVersion);

internal override string ToStringVcardInternal(Version cardVersion)
{
bool altIdSupported = cardVersion.Major >= 4;
if (altIdSupported)
{
bool installAltId = AltId >= 0 && Arguments.Length > 0;
return
$"{VcardConstants._emailSpecifier};" +
$"{(installAltId ? VcardConstants._altIdArgumentSpecifier + AltId + VcardConstants._fieldDelimiter : "")}" +
$"{VcardConstants._typeArgumentSpecifier}{string.Join(",", ElementTypes)}{VcardConstants._argumentDelimiter}" +
$"{ContactEmailAddress}";
}
else
{
return
$"{VcardConstants._emailSpecifier};" +
$"{VcardConstants._typeArgumentSpecifier}{string.Join(",", ElementTypes)}{VcardConstants._argumentDelimiter}" +
$"{ContactEmailAddress}";
}
}
internal override string ToStringVcardInternal(Version cardVersion) =>
ContactEmailAddress;

internal override BaseCardPartInfo FromStringVcardInternal(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion)
{
Expand Down
1 change: 0 additions & 1 deletion VisualCard/Parts/Implementations/GenderInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ internal static BaseCardPartInfo FromStringVcardStatic(string value, string[] fi
new GenderInfo().FromStringVcardInternal(value, finalArgs, altId, elementTypes, valueType, cardVersion);

internal override string ToStringVcardInternal(Version cardVersion) =>
$"{VcardConstants._genderSpecifier}{VcardConstants._argumentDelimiter}" +
(Gender != Gender.Unspecified ? Gender.ToString()[0] : "") +
(!string.IsNullOrEmpty(GenderDescription) ? $"{VcardConstants._fieldDelimiter}{GenderDescription}" : "");

Expand Down
21 changes: 2 additions & 19 deletions VisualCard/Parts/Implementations/GeoInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,8 @@ public class GeoInfo : BaseCardPartInfo, IEquatable<GeoInfo>
internal static BaseCardPartInfo FromStringVcardStatic(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion) =>
new GeoInfo().FromStringVcardInternal(value, finalArgs, altId, elementTypes, valueType, cardVersion);

internal override string ToStringVcardInternal(Version cardVersion)
{
bool altIdSupported = cardVersion.Major >= 4;
if (altIdSupported)
{
bool installAltId = AltId >= 0 && Arguments.Length > 0;
return
$"{VcardConstants._geoSpecifier}{(installAltId ? VcardConstants._fieldDelimiter : VcardConstants._argumentDelimiter)}" +
$"{(installAltId ? VcardConstants._altIdArgumentSpecifier + AltId + VcardConstants._fieldDelimiter : "")}" +
$"{(installAltId ? string.Join(VcardConstants._fieldDelimiter.ToString(), Arguments) + VcardConstants._argumentDelimiter : "")}" +
$"{Geo}";
}
else
{
return
$"{VcardConstants._geoSpecifier}:" +
$"{Geo}";
}
}
internal override string ToStringVcardInternal(Version cardVersion) =>
Geo;

internal override BaseCardPartInfo FromStringVcardInternal(string value, string[] finalArgs, int altId, string[] elementTypes, string valueType, Version cardVersion)
{
Expand Down
Loading

0 comments on commit c1644ef

Please sign in to comment.