Implement FN, ADR, BDAY, CATEGORIES, NICKNAME

This commit is contained in:
femsci 2023-12-27 00:06:26 +01:00
parent ce4eeccd54
commit 935cc26190
Signed by: femsci
GPG key ID: 08F7911F0E650C67

View file

@ -9,7 +9,12 @@ namespace Nyanbyte.IDShare.Vcf;
public class Vcard
{
public string FormattedName { get; set; } = string.Empty;
public ICollection<string> Nicknames { get; set; } = new HashSet<string>();
public DateTime? Birthday { get; set; }
public ICollection<string> Categories { get; set; } = new HashSet<string>();
public ICollection<VcardAddress> Addresses = new HashSet<VcardAddress>();
public static Vcard FromString(string data)
{
@ -32,10 +37,13 @@ public class Vcard
throw new ArgumentException("Invalid data: This implementation supports only VCF version 4.0.");
}
Vcard card = new();
foreach (string line in lines[2..^2])
{
string keyword = line[..line.IndexOf(':')];
string? type = null;
string value = line[(line.IndexOf(':') + 1)..];
if (keyword.Contains(';'))
{
type = keyword[(keyword.IndexOf(';') + 1)..];
@ -45,19 +53,20 @@ public class Vcard
switch (keyword)
{
case "ADR":
NotImplemented();
VcardAddress addr = VcardAddress.FromLine(line);
card.Addresses.Add(addr);
break;
case "BDAY":
NotImplemented();
card.Birthday = DateTime.ParseExact(value, "yyyyMMdd", null);
break;
case "CATEGORIES":
NotImplemented();
card.Categories = value.Split(',');
break;
case "EMAIL":
NotImplemented();
break;
case "FN":
NotImplemented();
card.FormattedName = value;
break;
case "GENDER":
NotImplemented();
@ -75,7 +84,7 @@ public class Vcard
NotImplemented();
break;
case "NICKNAME":
NotImplemented();
card.Nicknames = value.Split(',');
break;
case "NOTE":
NotImplemented();
@ -107,6 +116,10 @@ public class Vcard
}
}
if (string.IsNullOrWhiteSpace(card.FormattedName))
{
throw new ArgumentException("No FN provided.");
}
throw new NotImplementedException();
}
@ -120,9 +133,64 @@ public class Vcard
{
StringBuilder sb = new("BEGIN:VCARD\nVERSION:4.0;\n");
sb.AppendLine($"FN:{FormattedName}");
foreach (var addr in Addresses)
{
sb.AppendLine(addr.SerializeLine());
}
if (Birthday is not null)
{
sb.AppendLine($"BDAY:{Birthday.ToString:yyyyMMdd}");
}
if (Categories.Any())
{
sb.AppendLine($"CATEGORIES:{string.Join(',', Categories)}");
}
if (Nicknames.Any())
{
sb.AppendLine($"NICKNAME:{string.Join(',', Nicknames)}");
}
throw new NotImplementedException();
sb.Append("END:VCARD");
return sb.ToString();
}
}
//TODO Integrate Nyanbyte.Countries
public record VcardAddress(string AddressType, string? POBox, string? AptNumber, string? Street, string Locality, string? Region, string? POCode, string Country)
{
public static VcardAddress FromLine(string data)
{
int sep = data.IndexOf(':');
if (sep == -1)
{
throw new ArgumentException("Invalid data: No separating colon.");
}
string prefix = data[..sep];
//Len of "ADR;TYPE=" is 9
string type = prefix[9..];
string suffix = data[(sep + 1)..];
string[] values = suffix.Split(';');
if (values.Length != 7)
{
throw new ArgumentException($"Invalid data: Invalid number of data fields: Expected 7, got {values.Length}.");
}
return new VcardAddress(type, values[0], values[1], values[2], values[3], values[4], values[5], values[6]);
}
public string SerializeLine() => $"ADR;TYPE={AddressType}:{ToString}";
public override string ToString() => $"{POBox};{AptNumber};{Street};{Locality};{Region};{POCode};{Country}";
}