• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JaCraig / Archivist / 20796455660

07 Jan 2026 09:03PM UTC coverage: 78.836% (+0.8%) from 78.063%
20796455660

push

github

web-flow
Merge pull request #238 from JaCraig/dependabot/nuget/Archivist.Tests/dependencies-513ebfd917

chore: Bump the dependencies group with 1 update

2455 of 3412 branches covered (71.95%)

Branch coverage included in aggregate %.

3259 of 3836 relevant lines covered (84.96%)

6613.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.0
/Archivist/DataTypes/Table.cs
1
using Archivist.BaseClasses;
2
using Archivist.Converters;
3
using Archivist.Interfaces;
4
using System;
5
using System.Collections;
6
using System.Collections.Generic;
7
using System.Text;
8

9
namespace Archivist.DataTypes
10
{
11
    /// <summary>
12
    /// Represents a table in the Archivist system.
13
    /// </summary>
14
    /// <seealso cref="FileBaseClass{Table}"/>
15
    public class Table : FileBaseClass<Table>, IComparable<Table>, IEquatable<Table>, IListConvertable, IList<TableRow>
16
    {
17
        /// <summary>
18
        /// Initializes a new instance of the <see cref="Table"/> class.
19
        /// </summary>
20
        public Table()
21
            : this(null, ",")
7,412✔
22
        {
23
        }
7,412✔
24

25
        /// <summary>
26
        /// Initializes a new instance of the <see cref="Table"/> class.
27
        /// </summary>
28
        /// <param name="delimiter">The delimiter used by the table.</param>
29
        public Table(string delimiter)
30
            : this(null, delimiter)
×
31
        {
32
        }
×
33

34
        /// <summary>
35
        /// Initializes a new instance of the <see cref="Table"/> class.
36
        /// </summary>
37
        /// <param name="converter">The type converter.</param>
38
        /// <param name="delimiter">The delimiter used by the table.</param>
39
        public Table(Convertinator? converter, string delimiter = ",")
40
            : base(converter)
7,423✔
41
        {
42
            Delimiter = delimiter;
7,423✔
43
        }
7,423✔
44

45
        /// <summary>
46
        /// Gets the headers of the table.
47
        /// </summary>
48
        /// <value>The headers.</value>
49
        public List<string> Columns { get; } = new List<string>();
360,854✔
50

51
        /// <summary>
52
        /// Gets the number of rows in the table.
53
        /// </summary>
54
        public int Count => Rows.Count;
64✔
55

56
        /// <summary>
57
        /// Gets or sets the delimiter used by the table.
58
        /// </summary>
59
        public string Delimiter
60
        {
61
            get
62
            {
63
                _ = Metadata.TryGetValue("Delimiter", out var Delimiter);
7✔
64
                return Delimiter ?? ",";
7!
65
            }
66
            set => Metadata["Delimiter"] = value;
7,425✔
67
        }
68

69
        /// <summary>
70
        /// Gets a value indicating whether the table is read-only.
71
        /// </summary>
72
        public bool IsReadOnly => false;
2✔
73

74
        /// <summary>
75
        /// Gets the rows of the table.
76
        /// </summary>
77
        private List<TableRow> Rows { get; } = new List<TableRow>();
406,337✔
78

79
        /// <summary>
80
        /// Gets or sets the row at the specified index.
81
        /// </summary>
82
        /// <param name="index">The index of the table.</param>
83
        /// <returns>The row at the specified index.</returns>
84
        /// <exception cref="ArgumentOutOfRangeException">The index is out of range.</exception>
85
        public TableRow this[int index]
86
        {
87
            get
88
            {
89
                if (index < 0 || index >= Rows.Count)
128✔
90
                    throw new ArgumentOutOfRangeException(nameof(index));
1✔
91
                return Rows[index];
127✔
92
            }
93
            set
94
            {
95
                if (index < 0 || index >= Rows.Count)
2✔
96
                    throw new ArgumentOutOfRangeException(nameof(index));
1✔
97
                Rows[index] = value ?? new TableRow(Columns);
1!
98
            }
1✔
99
        }
100

101
        /// <summary>
102
        /// Converts the table to a calendar.
103
        /// </summary>
104
        /// <param name="file">The table to convert.</param>
105
        public static implicit operator Calendar?(Table? file)
106
        {
107
            return TableToCalendarConverter.Convert(file);
6✔
108
        }
109

110
        /// <summary>
111
        /// Converts the table to a card.
112
        /// </summary>
113
        /// <param name="file">The table to convert.</param>
114
        /// <returns>The card representation of the table.</returns>
115
        public static implicit operator Card?(Table? file)
116
        {
117
            return TableToCardConverter.Convert(file);
5✔
118
        }
119

120
        /// <summary>
121
        /// Converts the table to a feed.
122
        /// </summary>
123
        /// <param name="file">The table to convert.</param>
124
        /// <returns>The feed representation of the table.</returns>
125
        public static implicit operator Feed?(Table? file)
126
        {
127
            return TableToFeedConverter.Convert(file);
5✔
128
        }
129

130
        /// <summary>
131
        /// Converts the table to an image.
132
        /// </summary>
133
        /// <param name="file">The table to convert.</param>
134
        /// <returns>The image representation of the table.</returns>
135
        public static implicit operator Image?(Table? file)
136
        {
137
            return AnythingToImageConverter.Convert(file);
1✔
138
        }
139

140
        /// <summary>
141
        /// Converts the table to a structured object.
142
        /// </summary>
143
        /// <param name="file">The table to convert.</param>
144
        public static implicit operator StructuredObject?(Table? file)
145
        {
146
            return TableToStructuredObjectConverter.Convert(file);
2✔
147
        }
148

149
        /// <summary>
150
        /// Converts the table to a tables object.
151
        /// </summary>
152
        /// <param name="file">The table to convert.</param>
153
        /// <returns>The tables representation of the table.</returns>
154
        public static implicit operator Tables?(Table? file)
155
        {
156
            return TableToTablesConverter.Convert(file);
1✔
157
        }
158

159
        /// <summary>
160
        /// Converts the table to a text object.
161
        /// </summary>
162
        /// <param name="file">The table to convert.</param>
163
        /// <returns>The text representation of the table.</returns>
164
        public static implicit operator Text?(Table? file)
165
        {
166
            return AnythingToTextConverter.Convert(file);
2✔
167
        }
168

169
        /// <summary>
170
        /// Determines whether two table objects are not equal.
171
        /// </summary>
172
        /// <param name="left">The first table object.</param>
173
        /// <param name="right">The second table object.</param>
174
        /// <returns><c>true</c> if the two table objects are not equal; otherwise, <c>false</c>.</returns>
175
        public static bool operator !=(Table? left, Table? right)
176
        {
177
            return !(left == right);
6✔
178
        }
179

180
        /// <summary>
181
        /// Determines whether the first table object is less than the second table object.
182
        /// </summary>
183
        /// <param name="left">The first table object.</param>
184
        /// <param name="right">The second table object.</param>
185
        /// <returns>
186
        /// <c>true</c> if the first table object is less than the second table object; otherwise, <c>false</c>.
187
        /// </returns>
188
        public static bool operator <(Table? left, Table? right)
189
        {
190
            return left is null ? right is not null : left.CompareTo(right) < 0;
4✔
191
        }
192

193
        /// <summary>
194
        /// Determines whether the first table object is less than or equal to the second table object.
195
        /// </summary>
196
        /// <param name="left">The first table object.</param>
197
        /// <param name="right">The second table object.</param>
198
        /// <returns>
199
        /// <c>true</c> if the first table object is less than or equal to the second table object;
200
        /// otherwise, <c>false</c>.
201
        /// </returns>
202
        public static bool operator <=(Table? left, Table? right)
203
        {
204
            return left is null || left.CompareTo(right) <= 0;
4✔
205
        }
206

207
        /// <summary>
208
        /// Determines whether two table objects are equal.
209
        /// </summary>
210
        /// <param name="left">The first table object.</param>
211
        /// <param name="right">The second table object.</param>
212
        /// <returns><c>true</c> if the two table objects are equal; otherwise, <c>false</c>.</returns>
213
        public static bool operator ==(Table? left, Table? right)
214
        {
215
            if (left is null)
12✔
216
                return right is null;
4✔
217
            return left.Equals(right);
8✔
218
        }
219

220
        /// <summary>
221
        /// Determines whether the first table object is greater than the second table object.
222
        /// </summary>
223
        /// <param name="left">The first table object.</param>
224
        /// <param name="right">The second table object.</param>
225
        /// <returns>
226
        /// <c>true</c> if the first table object is greater than the second table object;
227
        /// otherwise, <c>false</c>.
228
        /// </returns>
229
        public static bool operator >(Table? left, Table? right)
230
        {
231
            return left?.CompareTo(right) > 0;
4✔
232
        }
233

234
        /// <summary>
235
        /// Determines whether the first table object is greater than or equal to the second table object.
236
        /// </summary>
237
        /// <param name="left">The first table object.</param>
238
        /// <param name="right">The second table object.</param>
239
        /// <returns>
240
        /// <c>true</c> if the first table object is greater than or equal to the second table
241
        /// object; otherwise, <c>false</c>.
242
        /// </returns>
243
        public static bool operator >=(Table? left, Table? right)
244
        {
245
            return left is null ? right is null : left.CompareTo(right) >= 0;
4✔
246
        }
247

248
        /// <summary>
249
        /// Adds a row to the table.
250
        /// </summary>
251
        /// <param name="item">The row to add to the table.</param>
252
        public void Add(TableRow? item) => Rows.Add(item ?? new TableRow(Columns));
353,041✔
253

254
        /// <summary>
255
        /// Adds a new row to the table.
256
        /// </summary>
257
        /// <returns>The new row.</returns>
258
        public TableRow AddRow()
259
        {
260
            var Row = new TableRow(Columns);
89✔
261
            Rows.Add(Row);
89✔
262
            return Row;
89✔
263
        }
264

265
        /// <summary>
266
        /// Clears the table.
267
        /// </summary>
268
        public void Clear() => Rows.Clear();
2✔
269

270
        /// <summary>
271
        /// Compares the current table object with another table object.
272
        /// </summary>
273
        /// <param name="other">The table object to compare with this table object.</param>
274
        /// <returns>A value that indicates the relative order of the table objects being compared.</returns>
275
        public override int CompareTo(Table? other)
276
        {
277
            if (other is null)
13✔
278
                return 1;
5✔
279
            return other.GetContent()?.CompareTo(GetContent()) ?? 1;
8!
280
        }
281

282
        /// <summary>
283
        /// Determines if the table contains the specified row.
284
        /// </summary>
285
        /// <param name="item">The row to find in the table.</param>
286
        /// <returns><c>true</c> if the table contains the row; otherwise, <c>false&gt;</c>.</returns>
287
        public bool Contains(TableRow? item) => item is not null && Rows.Contains(item);
3✔
288

289
        /// <summary>
290
        /// Copies the list object to the table.
291
        /// </summary>
292
        /// <typeparam name="TObject">The type of the object.</typeparam>
293
        /// <param name="obj">The list object to copy to the table.</param>
294
        public void ConvertFrom<TObject>(List<TObject?> obj)
295
        {
296
            obj ??= new List<TObject?>();
3✔
297
            Columns.Clear();
3✔
298
            Rows.Clear();
3✔
299
            foreach (System.Reflection.PropertyInfo Property in typeof(TObject).GetProperties())
12✔
300
            {
301
                Columns.Add(Property.Name);
3✔
302
            }
303
            foreach (TObject? Item in obj)
14✔
304
            {
305
                var Row = new TableRow(Columns);
4✔
306
                Row.ConvertFrom(Item);
4✔
307
                Rows.Add(Row);
4✔
308
            }
309
        }
3✔
310

311
        /// <summary>
312
        /// Converts this instance into the object array of the type specified.
313
        /// </summary>
314
        /// <typeparam name="TObject">The type of the object.</typeparam>
315
        /// <returns>The resulting array.</returns>
316
        public List<TObject?> ConvertTo<TObject>() => Rows.ConvertAll(x => x.ConvertTo<TObject?>());
5✔
317

318
        /// <summary>
319
        /// Copies the rows of the table to an array, starting at a particular array index.
320
        /// </summary>
321
        /// <param name="array">The array to copy the rows to.</param>
322
        /// <param name="arrayIndex">The index in the array at which to start copying the rows.</param>
323
        public void CopyTo(TableRow[]? array, int arrayIndex)
324
        {
325
            if (array is null || array.Length == 0)
3✔
326
                return;
2✔
327
            if (arrayIndex < 0 || arrayIndex >= array.Length)
1!
328
                throw new ArgumentOutOfRangeException(nameof(arrayIndex));
×
329
            var Count = Math.Min(array.Length - arrayIndex, Rows.Count);
1✔
330
            Rows.CopyTo(0, array, arrayIndex, Count);
1✔
331
        }
1✔
332

333
        /// <summary>
334
        /// Determines whether the current table object is equal to another table object.
335
        /// </summary>
336
        /// <param name="obj">The table object to compare with this table object.</param>
337
        /// <returns>
338
        /// <c>true</c> if the current table object is equal to the other table object; otherwise, <c>false</c>.
339
        /// </returns>
340
        public override bool Equals(object? obj) => obj is Table Table && Equals(Table);
6✔
341

342
        /// <summary>
343
        /// Determines whether the current table object is equal to another table object.
344
        /// </summary>
345
        /// <param name="other">The table object to compare with this table object.</param>
346
        /// <returns>
347
        /// <c>true</c> if the current table object is equal to the other table object; otherwise, <c>false</c>.
348
        /// </returns>
349
        public override bool Equals(Table? other)
350
        {
351
            if (ReferenceEquals(this, other))
14!
352
                return true;
×
353
            if (other is null)
14✔
354
                return false;
3✔
355
            return GetContent() == other.GetContent();
11✔
356
        }
357

358
        /// <summary>
359
        /// Gets the content of the table.
360
        /// </summary>
361
        /// <returns>The content of the table.</returns>
362
        public override string? GetContent()
363
        {
364
            return new StringBuilder()
83✔
365
                    .AppendJoin(' ', Columns)
83✔
366
                    .Append('\n')
83✔
367
                    .AppendJoin('\n', Rows)
83✔
368
                    .ToString();
83✔
369
        }
370

371
        /// <summary>
372
        /// Returns an enumerator that iterates through the rows of the table.
373
        /// </summary>
374
        /// <returns>An enumerator that can be used to iterate through the rows of the table.</returns>
375
        public IEnumerator<TableRow> GetEnumerator() => Rows.GetEnumerator();
45,339✔
376

377
        /// <summary>
378
        /// Returns an enumerator that iterates through the rows of the table.
379
        /// </summary>
380
        /// <returns>An enumerator that can be used to iterate through the rows of the table.</returns>
381
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
320✔
382

383
        /// <summary>
384
        /// Returns the hash code for the current table object.
385
        /// </summary>
386
        /// <returns>A hash code for the current table object.</returns>
387
        public override int GetHashCode()
388
        {
389
            var HashCode = new HashCode();
10✔
390
            foreach (var Column in Columns)
28✔
391
            {
392
                HashCode.Add(Column);
4✔
393
            }
394
            foreach (TableRow Row in Rows)
36✔
395
            {
396
                HashCode.Add(Row);
8✔
397
            }
398
            return HashCode.ToHashCode();
10✔
399
        }
400

401
        /// <summary>
402
        /// Returns the index of the specified row in the table.
403
        /// </summary>
404
        /// <param name="item">The row to find in the table.</param>
405
        /// <returns>The index of the row in the table.</returns>
406
        public int IndexOf(TableRow? item) => Rows.IndexOf(item!);
3✔
407

408
        /// <summary>
409
        /// Inserts a row into the table at the specified index.
410
        /// </summary>
411
        /// <param name="index">The index at which to insert the row.</param>
412
        /// <param name="item">The row to insert into the table.</param>
413
        public void Insert(int index, TableRow? item)
414
        {
415
            if (index < 0)
3!
416
                index = 0;
×
417
            if (index > Count)
3!
418
                index = Count;
×
419
            item ??= new TableRow(Columns);
3✔
420
            Rows.Insert(index, item);
3✔
421
        }
3✔
422

423
        /// <summary>
424
        /// Removes the first occurrence of a specific row from the table.
425
        /// </summary>
426
        /// <param name="item">The row to remove from the table.</param>
427
        /// <returns><c>true</c> if the row was successfully removed; otherwise, <c>false&gt;</c>.</returns>
428
        public bool Remove(TableRow? item) => item is not null && Rows.Remove(item);
8✔
429

430
        /// <summary>
431
        /// Removes the row at the specified index.
432
        /// </summary>
433
        /// <param name="index">The index of the row to remove.</param>
434
        public void RemoveAt(int index)
435
        {
436
            if (index < 0 || index >= Count)
4!
437
                return;
×
438
            Rows.RemoveAt(index);
4✔
439
        }
4✔
440

441
        /// <summary>
442
        /// Converts the table to the specified file type.
443
        /// </summary>
444
        /// <typeparam name="TFile">The type of the file.</typeparam>
445
        /// <returns>The file of the specified type.</returns>
446
        public override TFile? ToFileType<TFile>() where TFile : default
447
        {
448
            Type FileType = typeof(TFile);
6✔
449
            IGenericFile? ReturnValue;
450
            if (FileType == typeof(Card))
6✔
451
                ReturnValue = (Card?)this;
1✔
452
            else if (FileType == typeof(Calendar))
5!
453
                ReturnValue = (Calendar?)this;
×
454
            else if (FileType == typeof(Feed))
5!
455
                ReturnValue = (Feed?)this;
×
456
            else if (FileType == typeof(Image))
5!
457
                ReturnValue = (Image?)this;
×
458
            else if (FileType == typeof(Table))
5✔
459
                ReturnValue = this;
4✔
460
            else if (FileType == typeof(Tables))
1!
461
                ReturnValue = (Tables?)this;
×
462
            else if (FileType == typeof(Text))
1!
463
                ReturnValue = (Text?)this;
×
464
            else if (FileType == typeof(StructuredObject))
1!
465
                ReturnValue = (StructuredObject?)this;
×
466
            else
467
                ReturnValue = (IGenericFile?)Converter?.Convert(this, FileType);
1!
468

469
            return (TFile?)ReturnValue;
6✔
470
        }
471
    }
472
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc