-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from SKProCH/dev
Add YandexId type to handle cursed Yandex ids (long/guid)
- Loading branch information
Showing
15 changed files
with
293 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
using System; | ||
|
||
namespace YandexMusicResolver.Ids; | ||
|
||
/// <summary> | ||
/// Holds the yandex track id | ||
/// </summary> | ||
/// <remarks> | ||
/// Since Yandex fucked up as usual, it will return an <see cref="long"/> ids for yandex's track, but will return <see cref="Guid"/> ids for user uploaded tracks | ||
/// </remarks> | ||
public struct YandexId { | ||
private long? _longId; | ||
private Guid? _guidId; | ||
|
||
/// <summary> | ||
/// Gets the <see cref="Guid"/> id | ||
/// </summary> | ||
/// <exception cref="InvalidOperationException">Current Id is not an Guid type. You can look at <see cref="IdType"/> to determine proper id type</exception> | ||
public Guid GuidId { | ||
get => _guidId ?? throw new InvalidOperationException($"Current Id is not an Guid type. Current type is {IdType}"); | ||
set => _guidId = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the <see cref="long"/> id | ||
/// </summary> | ||
/// <exception cref="InvalidOperationException">Current Id is not an long type. You can look at <see cref="IdType"/> to determine proper id type</exception> | ||
public long LongId { | ||
get => _longId ?? throw new InvalidOperationException($"Current Id is not an long type. Current type is {IdType}"); | ||
set => _longId = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the current id type | ||
/// </summary> | ||
public YandexIdType IdType { get; } | ||
|
||
/// <summary> | ||
/// Creates <see cref="YandexId"/> with <see cref="Guid"/> id | ||
/// </summary> | ||
/// <param name="id">The <see cref="Guid"/> id</param> | ||
public YandexId(Guid id) { | ||
IdType = YandexIdType.Guid; | ||
_guidId = id; | ||
} | ||
|
||
/// <summary> | ||
/// Creates <see cref="YandexId"/> with <see cref="long"/> id | ||
/// </summary> | ||
/// <param name="id">The <see cref="long"/> id</param> | ||
public YandexId(long id) { | ||
IdType = YandexIdType.Long; | ||
_longId = id; | ||
} | ||
|
||
/// <summary> | ||
/// Allows to implicitly cast <see cref="YandexId"/> to <see cref="Guid"/> | ||
/// </summary> | ||
/// <param name="yandexId">Instance of <see cref="YandexId"/></param> | ||
/// <returns>The <see cref="Guid"/> value</returns> | ||
public static implicit operator Guid(YandexId yandexId) => yandexId.GuidId; | ||
|
||
/// <summary> | ||
/// Allows to implicitly cast <see cref="YandexId"/> to <see cref="long"/> | ||
/// </summary> | ||
/// <param name="yandexId">Instance of <see cref="YandexId"/></param> | ||
/// <returns>The <see cref="long"/> value</returns> | ||
public static implicit operator long(YandexId yandexId) => yandexId.LongId; | ||
|
||
/// <summary> | ||
/// Allows to implicitly cast <see cref="long"/> to <see cref="YandexId"/> | ||
/// </summary> | ||
/// <param name="id"><see cref="long"/> value</param> | ||
/// <returns>The <see cref="YandexId"/> intance</returns> | ||
public static implicit operator YandexId(long id) => new(id); | ||
|
||
/// <summary> | ||
/// Allows to implicitly cast <see cref="Guid"/> to <see cref="YandexId"/> | ||
/// </summary> | ||
/// <param name="id"><see cref="Guid"/> value</param> | ||
/// <returns>The <see cref="YandexId"/> intance</returns> | ||
public static implicit operator YandexId(Guid id) => new(id); | ||
|
||
/// <inheritdoc /> | ||
public override string ToString() { | ||
if (_longId is not null) { | ||
return _longId.ToString(); | ||
} | ||
|
||
if (_guidId is not null) { | ||
return _guidId.ToString(); | ||
} | ||
|
||
throw new NotSupportedException("Current Id type doesn't support to string conversion. Report this to the library author"); | ||
} | ||
|
||
/// <summary> | ||
/// Tries to parse <see cref="YandexId"/> from the string | ||
/// </summary> | ||
/// <param name="s"><see cref="string"/> to parse the Id</param> | ||
/// <returns>Instance of <see cref="YandexId"/></returns> | ||
/// <exception cref="NotSupportedException">Current string cannot be converted to any known Id type. Check the string</exception> | ||
public static YandexId Parse(string s) { | ||
if (Guid.TryParse(s, out var guid)) { | ||
return new YandexId(guid); | ||
} | ||
|
||
if (long.TryParse(s, out var l)) { | ||
return new YandexId(l); | ||
} | ||
|
||
throw new NotSupportedException("Current string cannot be converted to any known Id type. Check the string"); | ||
} | ||
|
||
/// <summary> | ||
/// Available types of Yandex ids | ||
/// </summary> | ||
public enum YandexIdType { | ||
/// <summary> | ||
/// Current id is long | ||
/// </summary> | ||
Long, | ||
/// <summary> | ||
/// Current id is Guid | ||
/// </summary> | ||
Guid | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace YandexMusicResolver.Ids; | ||
|
||
/// <summary> | ||
/// Allows to properly serialize/deserialize the <see cref="YandexId"/> from JSON | ||
/// </summary> | ||
public class YandexIdConverter : JsonConverter<YandexId> { | ||
/// <inheritdoc /> | ||
public override YandexId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { | ||
if (reader.TokenType == JsonTokenType.String) { | ||
var s = reader.GetString(); | ||
if (long.TryParse(s, out var l)) { | ||
return new YandexId(l); | ||
} | ||
|
||
if (Guid.TryParse(s, out var guid)) { | ||
return new YandexId(guid); | ||
} | ||
} | ||
else if (reader.TokenType == JsonTokenType.Number) { | ||
var int64 = reader.GetInt64(); | ||
return new YandexId(int64); | ||
} | ||
throw new NotSupportedException("Current value seems doesn't look like any known YandexId type"); | ||
} | ||
/// <inheritdoc /> | ||
public override void Write(Utf8JsonWriter writer, YandexId value, JsonSerializerOptions options) { | ||
switch (value.IdType) { | ||
case YandexId.YandexIdType.Long: | ||
writer.WriteNumberValue(value.LongId); | ||
break; | ||
case YandexId.YandexIdType.Guid: | ||
writer.WriteStringValue(value.GuidId); | ||
break; | ||
default: | ||
throw new ArgumentOutOfRangeException(nameof(value.IdType), "Current YandexId type can't be wrote to JSON"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.