Implemented Model
This commit is contained in:
parent
9331aaf8d0
commit
8aa236233a
8 changed files with 143 additions and 26 deletions
|
|
@ -16,7 +16,20 @@ public sealed class ByHourComparer : ComparerBase, IComparer<Teacher>
|
|||
|
||||
public int Compare(Teacher? x, Teacher? y)
|
||||
{
|
||||
// TODO
|
||||
return -1;
|
||||
int nullCheck = CheckNull(x, y);
|
||||
if (nullCheck != 2)
|
||||
{
|
||||
return nullCheck;
|
||||
}
|
||||
|
||||
// Ignore possibility of null, bc we already checked it above
|
||||
int dayComparison = CompareEnum(x!.ConsultingHourWeekDay, y!.ConsultingHourWeekDay);
|
||||
if (dayComparison != 0)
|
||||
{
|
||||
return ApplyCorrectDirection(dayComparison);
|
||||
}
|
||||
|
||||
int unitComparison = CompareEnum(x.ConsultingHourUnit, y.ConsultingHourUnit);
|
||||
return ApplyCorrectDirection(unitComparison);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,12 @@ public sealed class ByNameComparer : ComparerBase, IComparer<Teacher>
|
|||
|
||||
public int Compare(Teacher? x, Teacher? y)
|
||||
{
|
||||
// TODO
|
||||
return -1;
|
||||
int nullCheck = CheckNull(x, y);
|
||||
if (nullCheck != 2)
|
||||
{
|
||||
return nullCheck;
|
||||
}
|
||||
|
||||
return ApplyCorrectDirection(string.Compare(x!.Name, y!.Name, StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,19 @@ public sealed class ByRoomComparer : IComparer<Teacher>
|
|||
{
|
||||
public int Compare(Teacher? x, Teacher? y)
|
||||
{
|
||||
// TODO
|
||||
if (x == null && y == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (x == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (y == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return string.Compare(x!.Room, y!.Room, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,58 @@ public abstract class ComparerBase
|
|||
/// </summary>
|
||||
protected bool Ascending { get; }
|
||||
|
||||
// TODO: consider moving the basic RefEquals code of CompareTo from the subclasses here
|
||||
// maybe also rename this to SortOrderComparerBase or something and introduce another, common base class for all three?
|
||||
/// <summary>
|
||||
/// Checks if a <see cref="Teacher"/> is null
|
||||
/// </summary>
|
||||
/// <param name="x">Teacher x</param>
|
||||
/// <param name="y">Teacher y</param>
|
||||
/// <returns>0 if both are null, the comparison if only one is null and 2 if both are NOT null</returns>
|
||||
protected int CheckNull(Teacher? x, Teacher? y)
|
||||
{
|
||||
if (x == null && y == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (x == null)
|
||||
{
|
||||
return Ascending ? 1 : -1;
|
||||
}
|
||||
if (y == null)
|
||||
{
|
||||
return Ascending ? -1 : 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the two enums
|
||||
/// </summary>
|
||||
/// <param name="x">First enum</param>
|
||||
/// <param name="y">Second enum</param>
|
||||
/// <typeparam name="TEnum">Enum Type</typeparam>
|
||||
/// <returns>The comparison</returns>
|
||||
protected int CompareEnum<TEnum>(TEnum? x, TEnum? y) where TEnum : struct, Enum
|
||||
{
|
||||
if (!x.HasValue && !y.HasValue)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!x.HasValue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (!y.HasValue)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return x.Value.CompareTo(y.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the correct direction
|
||||
/// </summary>
|
||||
/// <param name="comparison">The comparison</param>
|
||||
/// <returns><param name="comparison"> if <see cref="Ascending"/> is true, else returns negated value</param></returns>
|
||||
protected int ApplyCorrectDirection(int comparison) => Ascending ? comparison : -comparison;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ public sealed class CsvData
|
|||
/// Gets a CSV header based on <see cref="HeaderNames" />
|
||||
/// </summary>
|
||||
/// <returns>A CSV header line</returns>
|
||||
public string GetHeader() => null!; // TODO
|
||||
public string GetHeader() => string.Join(Separator.ToString(), HeaderNames);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a CSV data line based on <see cref="Data" />
|
||||
/// </summary>
|
||||
/// <returns>A CSV data line</returns>
|
||||
public string GetData() => null!; // TODO
|
||||
public string GetData() => string.Join(Separator.ToString(), Data);
|
||||
|
||||
/// <summary>
|
||||
/// Allows to deconstruct the object into its header and data parts
|
||||
|
|
@ -50,8 +50,7 @@ public sealed class CsvData
|
|||
/// <param name="data">Set to <see cref="Data" /></param>
|
||||
public void Deconstruct(out IReadOnlyList<string> headerNames, out IReadOnlyList<string> data)
|
||||
{
|
||||
// TODO
|
||||
headerNames = null!;
|
||||
data = null!;
|
||||
headerNames = HeaderNames;
|
||||
data = Data;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,10 +45,25 @@ public class Teacher : ICsvRepresentable
|
|||
{
|
||||
get
|
||||
{
|
||||
// TODO
|
||||
return null!;
|
||||
if (ConsultingHour == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ConsultingHourUnit == null ? ConsultingHour.ToString() : $"{ConsultingHour} ({ConsultingHourUnit})";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual CsvData ToCsvData() => null!; // TODO
|
||||
public virtual CsvData ToCsvData()
|
||||
{
|
||||
List<string> headerNames = ["Name", "Day", "ConsultingHour", "Room"];
|
||||
List<string> dataLine = [
|
||||
Name,
|
||||
ConsultingHourWeekDay?.ToString() ?? string.Empty,
|
||||
ConsultingHourTime ?? string.Empty,
|
||||
Room ?? string.Empty
|
||||
];
|
||||
var data = new CsvData(headerNames, dataLine);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,16 @@ public sealed class TeacherWithBusinessCard : Teacher
|
|||
|
||||
public override CsvData ToCsvData()
|
||||
{
|
||||
// TODO (remember to maybe use the base implementation...)
|
||||
return null!;
|
||||
var data = base.ToCsvData();
|
||||
(IReadOnlyList<string> headerNamesBase, IReadOnlyList<string> dataLineBase) = data;
|
||||
|
||||
var headerNames = (List<string>)headerNamesBase;
|
||||
var dataLine = (List<string>)dataLineBase;
|
||||
|
||||
headerNames.Add("Image");
|
||||
dataLine.Add($"{BaseUrl}/{Id}");
|
||||
|
||||
var csvData = new CsvData(headerNames, dataLine);
|
||||
return csvData;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,18 +21,30 @@ public readonly record struct TimeFrame(TimeOnly Start, TimeOnly End)
|
|||
/// <returns>True if time frame could be parsed successfully; false otherwise</returns>
|
||||
public static bool TryParse(string timeFrame, out TimeFrame? result)
|
||||
{
|
||||
// TODO
|
||||
result = null;
|
||||
string[] timeFrames = timeFrame.Split("-");
|
||||
if (timeFrames.Length != 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TimeOnly.TryParse(timeFrames[0], out TimeOnly start) || !TimeOnly.TryParse(timeFrames[1], out TimeOnly end))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (start > end)
|
||||
{
|
||||
(start, end) = (end, start);
|
||||
}
|
||||
|
||||
result = new TimeFrame(start, end);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string representation of the time frame in format HH:MM-HH:MM
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
// TODO
|
||||
return null!;
|
||||
}
|
||||
public override string ToString() => $"{Start}-{End}";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue