/// <summary> /// Constructs an unbounded unit-of-time of the specified kind. /// </summary> /// <param name="unitOfTimeKind">The kind of unit-of-time.</param> /// <returns> /// The unbounded unit-of-time. /// </returns> /// <exception cref="ArgumentException"><paramref name="unitOfTimeKind"/> is <see cref="UnitOfTimeKind.Invalid"/>.</exception> public static UnitOfTime ToUnbounded( this UnitOfTimeKind unitOfTimeKind) { if (unitOfTimeKind == UnitOfTimeKind.Invalid) { throw new ArgumentOutOfRangeException(Invariant($"'{nameof(unitOfTimeKind)}' == '{UnitOfTimeKind.Invalid}'"), (Exception)null); } UnitOfTime result; switch (unitOfTimeKind) { case UnitOfTimeKind.Calendar: result = new CalendarUnbounded(); break; case UnitOfTimeKind.Fiscal: result = new FiscalUnbounded(); break; case UnitOfTimeKind.Generic: result = new GenericUnbounded(); break; default: throw new NotSupportedException(Invariant($"This {nameof(UnitOfTimeKind)} is not supported: {unitOfTimeKind}.")); } return(result); }
public static UnitOfTime DeserializeFromSortableString( this string unitOfTime, Type type) { if (!type.IsUnitOfTimeType()) { throw new NotSupportedException(Invariant($"Unsupported type {type?.FullName ?? "<NULL TYPE>"}, expected an implmenter {nameof(UnitOfTime)}")); } if (type == null) { throw new ArgumentNullException(nameof(type)); } if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } if (string.IsNullOrWhiteSpace(unitOfTime)) { throw new ArgumentException(Invariant($"'{nameof(unitOfTime)}' is white space")); } var serializationFormatMatch = SerializationFormatByType.Select(_ => new { Match = _.Regex.Match(unitOfTime), SerializationFormat = _ }).SingleOrDefault(_ => _.Match.Success); if (serializationFormatMatch == null) { throw new InvalidOperationException("Cannot deserialize string; it is not valid unit-of-time."); } var serializedType = serializationFormatMatch.SerializationFormat.Type; if (!type.IsAssignableFrom(serializedType)) { throw new InvalidOperationException(Invariant($"The unit-of-time appears to be a {serializedType.Name} which cannot be casted to a {type.Name}.")); } string errorMessage = Invariant($"Cannot deserialize string; it appears to be a {serializedType.Name} but it is malformed."); var tokens = serializationFormatMatch.SerializationFormat.Regex.GetGroupNames().Skip(1).Select(_ => serializationFormatMatch.Match.Groups[_].Value).ToArray(); if (serializedType == typeof(CalendarDay)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var month = ParseEnumOrThrow <MonthOfYear>(tokens[1], errorMessage); var day = ParseEnumOrThrow <DayOfMonth>(tokens[2], errorMessage); try { var result = new CalendarDay(year, month, day); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(CalendarMonth)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var month = ParseEnumOrThrow <MonthOfYear>(tokens[1], errorMessage); try { var result = new CalendarMonth(year, month); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(CalendarQuarter)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var quarter = ParseEnumOrThrow <QuarterNumber>(tokens[1], errorMessage); try { var result = new CalendarQuarter(year, quarter); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(CalendarYear)) { var year = ParseIntOrThrow(tokens[0], errorMessage); try { var result = new CalendarYear(year); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(CalendarUnbounded)) { var result = new CalendarUnbounded(); return(result); } if (serializedType == typeof(FiscalMonth)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var month = ParseEnumOrThrow <MonthNumber>(tokens[1], errorMessage); try { var result = new FiscalMonth(year, month); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(FiscalQuarter)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var quarter = ParseEnumOrThrow <QuarterNumber>(tokens[1], errorMessage); try { var result = new FiscalQuarter(year, quarter); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(FiscalYear)) { var year = ParseIntOrThrow(tokens[0], errorMessage); try { var result = new FiscalYear(year); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(FiscalUnbounded)) { var result = new FiscalUnbounded(); return(result); } if (serializedType == typeof(GenericMonth)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var month = ParseEnumOrThrow <MonthNumber>(tokens[1], errorMessage); try { var result = new GenericMonth(year, month); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(GenericQuarter)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var quarter = ParseEnumOrThrow <QuarterNumber>(tokens[1], errorMessage); try { var result = new GenericQuarter(year, quarter); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(GenericYear)) { var year = ParseIntOrThrow(tokens[0], errorMessage); try { var result = new GenericYear(year); return(result); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(GenericUnbounded)) { var result = new GenericUnbounded(); return(result); } throw new NotSupportedException("this type of unit-of-time is not supported: " + serializedType); }