Skip to content

Commit

Permalink
Add a dedicated TimeSpan reader so it doesn't suck (discord-net#1005)
Browse files Browse the repository at this point in the history
* Add a dedicated TimeSpan reader so it doesn't suck

* Pass input as lower case
  • Loading branch information
Joe4evr authored and foxbot committed May 24, 2018
1 parent c275e57 commit b52af7a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/Discord.Net.Commands/CommandService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ public CommandService(CommandServiceConfig config)
_defaultTypeReaders[typeof(Nullable<>).MakeGenericType(type)] = NullableTypeReader.Create(type, _defaultTypeReaders[type]);
}

var tsreader = new TimeSpanTypeReader();
_defaultTypeReaders[typeof(TimeSpan)] = tsreader;
_defaultTypeReaders[typeof(TimeSpan?)] = NullableTypeReader.Create(typeof(TimeSpan), tsreader);

_defaultTypeReaders[typeof(string)] =
new PrimitiveTypeReader<string>((string x, out string y) => { y = x; return true; }, 0);

Expand Down
4 changes: 2 additions & 2 deletions src/Discord.Net.Commands/PrimitiveParsers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;

Expand Down Expand Up @@ -29,7 +29,7 @@ static IReadOnlyDictionary<Type, Delegate> CreateParsers()
parserBuilder[typeof(decimal)] = (TryParseDelegate<decimal>)decimal.TryParse;
parserBuilder[typeof(DateTime)] = (TryParseDelegate<DateTime>)DateTime.TryParse;
parserBuilder[typeof(DateTimeOffset)] = (TryParseDelegate<DateTimeOffset>)DateTimeOffset.TryParse;
parserBuilder[typeof(TimeSpan)] = (TryParseDelegate<TimeSpan>)TimeSpan.TryParse;
//parserBuilder[typeof(TimeSpan)] = (TryParseDelegate<TimeSpan>)TimeSpan.TryParse;
parserBuilder[typeof(char)] = (TryParseDelegate<char>)char.TryParse;
return parserBuilder.ToImmutable();
}
Expand Down
35 changes: 35 additions & 0 deletions src/Discord.Net.Commands/Readers/TimeSpanTypeReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Globalization;
using System.Threading.Tasks;

namespace Discord.Commands
{
internal class TimeSpanTypeReader : TypeReader
{
private static readonly string[] _formats = new[]
{
"%d'd'%h'h'%m'm'%s's'", //4d3h2m1s
"%d'd'%h'h'%m'm'", //4d3h2m
"%d'd'%h'h'%s's'", //4d3h 1s
"%d'd'%h'h'", //4d3h
"%d'd'%m'm'%s's'", //4d 2m1s
"%d'd'%m'm'", //4d 2m
"%d'd'%s's'", //4d 1s
"%d'd'", //4d
"%h'h'%m'm'%s's'", // 3h2m1s
"%h'h'%m'm'", // 3h2m
"%h'h'%s's'", // 3h 1s
"%h'h'", // 3h
"%m'm'%s's'", // 2m1s
"%m'm'", // 2m
"%s's'", // 1s
};

public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
{
return (TimeSpan.TryParseExact(input.ToLowerInvariant(), _formats, CultureInfo.InvariantCulture, out var timeSpan))
? Task.FromResult(TypeReaderResult.FromSuccess(timeSpan))
: Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Failed to parse TimeSpan"));
}
}
}

0 comments on commit b52af7a

Please sign in to comment.