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 class Vcard
{ {
public string FormattedName { get; set; } = string.Empty;
public ICollection<string> Nicknames { get; set; } = new HashSet<string>();
public DateTime? Birthday { get; set; } 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) 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."); throw new ArgumentException("Invalid data: This implementation supports only VCF version 4.0.");
} }
Vcard card = new();
foreach (string line in lines[2..^2]) foreach (string line in lines[2..^2])
{ {
string keyword = line[..line.IndexOf(':')]; string keyword = line[..line.IndexOf(':')];
string? type = null; string? type = null;
string value = line[(line.IndexOf(':') + 1)..];
if (keyword.Contains(';')) if (keyword.Contains(';'))
{ {
type = keyword[(keyword.IndexOf(';') + 1)..]; type = keyword[(keyword.IndexOf(';') + 1)..];
@ -45,19 +53,20 @@ public class Vcard
switch (keyword) switch (keyword)
{ {
case "ADR": case "ADR":
NotImplemented(); VcardAddress addr = VcardAddress.FromLine(line);
card.Addresses.Add(addr);
break; break;
case "BDAY": case "BDAY":
NotImplemented(); card.Birthday = DateTime.ParseExact(value, "yyyyMMdd", null);
break; break;
case "CATEGORIES": case "CATEGORIES":
NotImplemented(); card.Categories = value.Split(',');
break; break;
case "EMAIL": case "EMAIL":
NotImplemented(); NotImplemented();
break; break;
case "FN": case "FN":
NotImplemented(); card.FormattedName = value;
break; break;
case "GENDER": case "GENDER":
NotImplemented(); NotImplemented();
@ -75,7 +84,7 @@ public class Vcard
NotImplemented(); NotImplemented();
break; break;
case "NICKNAME": case "NICKNAME":
NotImplemented(); card.Nicknames = value.Split(',');
break; break;
case "NOTE": case "NOTE":
NotImplemented(); NotImplemented();
@ -107,6 +116,10 @@ public class Vcard
} }
} }
if (string.IsNullOrWhiteSpace(card.FormattedName))
{
throw new ArgumentException("No FN provided.");
}
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -120,9 +133,64 @@ public class Vcard
{ {
StringBuilder sb = new("BEGIN:VCARD\nVERSION:4.0;\n"); 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(); throw new NotImplementedException();
sb.Append("END:VCARD"); sb.Append("END:VCARD");
return sb.ToString(); 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}";
}