-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathContactStore.cs
More file actions
100 lines (85 loc) · 2.69 KB
/
Copy pathContactStore.cs
File metadata and controls
100 lines (85 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
internal enum AppTheme
{
[Description("Use system setting")]
System,
[Description("Light mode")]
Light,
[Description("Dark mode")]
Dark,
[Description("High contrast")]
HighContrast,
}
[Flags]
internal enum ContactPermissions
{
[Description("View contacts")]
Read = 1,
[Description("Create and edit contacts")]
Write = 2,
[Description("Remove contacts")]
Delete = 4,
[Description("Full administrative access")]
Admin = 8,
}
internal sealed record Contact(
[property: Display(Order = 0)] string Name,
[property: Display(Order = 1)] string Email);
internal sealed record ImportSummary(int Imported, int Overwritten, int Skipped);
internal interface IContactStore
{
IReadOnlyList<Contact> All();
void Add(Contact contact);
void Clear();
Task<IReadOnlyList<Contact>> ParseFileAsync(string file, CancellationToken cancellationToken);
int CountDuplicates(IReadOnlyList<Contact> batch);
bool IsDuplicate(Contact contact);
Task<bool> ImportOneAsync(Contact contact, CancellationToken cancellationToken);
}
internal sealed class InMemoryContactStore : IContactStore
{
private readonly List<Contact> _contacts =
[
new Contact("Carl de Billy", "carl@gmail.com"),
new Contact("Bob Smith", "bob@company.com"),
];
public IReadOnlyList<Contact> All() => _contacts;
public void Add(Contact contact)
{
ArgumentNullException.ThrowIfNull(contact);
_contacts.Add(contact);
}
public void Clear() => _contacts.Clear();
public Task<IReadOnlyList<Contact>> ParseFileAsync(string file, CancellationToken cancellationToken)
{
var baseName = Path.GetFileNameWithoutExtension(file);
IReadOnlyList<Contact> batch =
[
new Contact("Alice Martin", "alice@example.com"),
new Contact("Bob Smith", "bob@company.com"), // duplicate
new Contact("Charlie Brown", "charlie@example.com"),
new Contact("Carl de Billy", "carl@gmail.com"), // duplicate
new Contact($"{baseName} User", $"{baseName.ToLowerInvariant()}@import.com"),
];
return Task.FromResult(batch);
}
public int CountDuplicates(IReadOnlyList<Contact> batch) =>
batch.Count(b => IsDuplicate(b));
public bool IsDuplicate(Contact contact) =>
_contacts.Any(c => string.Equals(c.Name, contact.Name, StringComparison.OrdinalIgnoreCase));
public async Task<bool> ImportOneAsync(Contact contact, CancellationToken cancellationToken)
{
await Task.Delay(50, cancellationToken);
var existing = _contacts.FirstOrDefault(c =>
string.Equals(c.Name, contact.Name, StringComparison.OrdinalIgnoreCase));
if (existing is not null)
{
_contacts.Remove(existing);
_contacts.Add(contact);
return true;
}
_contacts.Add(contact);
return false;
}
}