Implement FN, ADR, BDAY, CATEGORIES, NICKNAME
This commit is contained in:
parent
ce4eeccd54
commit
935cc26190
1 changed files with 73 additions and 5 deletions
|
@ -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}";
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue