Adds documentation text for the SDK.

This commit is contained in:
Serraniel 2023-03-03 17:49:56 +01:00
parent 33c96b9375
commit 6ccaab2ed4
Signed by: Serraniel
GPG key ID: 3690B4E7364525D3
9 changed files with 286 additions and 24 deletions

View file

@ -4,18 +4,43 @@ using JpnCardsPokemon.Sdk.Utils.JsonConverter;
namespace JpnCardsPokemon.Sdk.Api;
/// <summary>
/// Represents a card object from the web api.
/// </summary>
public class Card
{
/// <summary>
/// The name of the card.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// The internal identification number that the card is given. Used to query for this single card.
/// </summary>
public int Id { get; set; }
[JsonPropertyName("setData")] public Set? Set { get; set; }
/// <summary>
/// Reduced information about the set the card belongs to.
/// </summary>
/// <remarks>May contain basic information only. It´s recommended to fetch the fully <see cref="Set" /> separately.</remarks>
[JsonPropertyName("setData")]
public Set? Set { get; set; }
/// <summary>
/// The energy type of types the card is.
/// </summary>
/// <remarks>Almost always will be a single value.</remarks>
public string[]? Types { get; set; }
/// <summary>
/// The amount of HP the card has.
/// </summary>
/// <remarks>If the card does not have HP, the value will be -1.</remarks>
public int Hp { get; set; } = -1;
/// <summary>
/// If the card evolves from another card, this field will denote the name of the pre-evolution.
/// </summary>
public string? EvolvesFrom { get; set; }
// TODO: Type of property is not documented. Has to be evaluated at a later time.
@ -24,39 +49,88 @@ public class Card
// TODO: Type of property is not documented. Has to be evaluated at a later time.
// public Attack[]? Attacks { get; set; }
/// <summary>
/// Describes rules the card is bound to. Mainly for cards with a rule box and certain Trainers.
/// </summary>
public string[]? Rules { get; set; }
// TODO: Type of property is not documented. Has to be evaluated at a later time.
// public Weakness[]? Weaknesses { get; set; }
// TODO: Type of property is not documented. Has to be evaluated at a later time.
// public Resistance[]? Ressistences { get; set; }
// public Resistance[]? Resistances { get; set; }
/// <summary>
/// A list of known prices for this card.
/// </summary>
/// <remarks>May contain entries from different sellers, versions and conditions.</remarks>
[JsonConverter(typeof(CardPricesJsonConverter))]
public IEnumerable<CardPrice>? Prices { get; set; }
[JsonPropertyName("retreatCost")] public string[]? RetreatCosts { get; set; }
/// <summary>
/// List of the energies required to retreat.
/// </summary>
[JsonPropertyName("retreatCost")]
public string[]? RetreatCosts { get; set; }
/// <summary>
/// The total number of energies needed to retreat.
/// </summary>
public int? ConvertedRetreatCost { get; set; }
/// <summary>
/// The supertype the card is.
/// </summary>
/// <remarks>Only possibilities are 'Pokemon', 'Trainer' or 'Energy'.</remarks>
public string? Supertype { get; set; }
/// <summary>
/// The subsets that the card falls into. For example 'Single Strike Pokemon', 'Pokemon VMAX', etc.
/// </summary>
public string[]? Subtypes { get; set; }
/// <summary>
/// The rarity of the card.
/// </summary>
public string? Rarity { get; set; }
// TODO: Type of property is not documented. Has to be evaluated at a later time.
// public Legality[]? Legalities { get; set; }
/// <summary>
/// The card art's artist.
/// </summary>
public string? Artist { get; set; }
/// <summary>
/// The url pointing to the card's image.
/// </summary>
/// <remarks>
/// If there is no card image, then this will instead point to
/// https://assets.tcgcollector.com/build/images/default-card-image.789f6232.png.
/// </remarks>
public string? ImageUrl { get; set; }
/// <summary>
/// The URL which leads to the original card URL data.
/// </summary>
public string? CardUrl { get; set; }
[JsonPropertyName("sequenceNumber")] public int Number { get; set; }
/// <summary>
/// The sequential number of the card (applicable to Secret Rares).
/// </summary>
[JsonPropertyName("sequenceNumber")]
public int Number { get; set; }
/// <summary>
/// The number printed on the card. Will be the same as <see cref="Number" /> almost always. Is relevant for
/// promotional cards, such as SWSH001.
/// </summary>
public string? PrintedNumber { get; set; }
/// <summary>
/// A stable id for earch card. Output is an eight digit integer which is unique for each card. While the cards'
/// <see cref="Id" /> may change over time, the uuid should always remain stable and constant.
/// </summary>
public int Uuid { get; set; }
}

View file

@ -3,19 +3,50 @@ using System.Text.Json.Serialization;
namespace JpnCardsPokemon.Sdk.Api;
/// <summary>
/// Contains information about card price.
/// </summary>
public class CardPrice
{
/// <summary>
/// Specifies the card version. Almost always will be 'Regular' but may contain other versions like 'Reverse Holo',
/// etc.
/// </summary>
public string? Version { get; set; }
/// <summary>
/// Specifies the card condition. Often will be a rating in format of 'A+', 'A', etc. but also can be 'NM' or other
/// similar descriptive strings.
/// </summary>
public string? Condition { get; set; }
[JsonPropertyName("priceAmount")] public decimal Price { get; set; }
/// <summary>
/// The actual price for the specified version and condition.
/// </summary>
[JsonPropertyName("priceAmount")]
public decimal Price { get; set; }
[JsonPropertyName("priceCurrency")] public string? Currency { get; set; }
/// <summary>
/// The currency used for the <see cref="Price" />.
/// </summary>
/// <remarks>Almost always will be 'JYP' for Japanese Yen.</remarks>
[JsonPropertyName("priceCurrency")]
public string? Currency { get; set; }
[JsonPropertyName("dateUpdated")] public DateTime? UpdatedDate { get; set; }
/// <summary>
/// Date when the price information was updated last.
/// </summary>
[JsonPropertyName("dateUpdated")]
public DateTime? UpdatedDate { get; set; }
[JsonPropertyName("listingUrl")] public string? ListingUrl { get; set; }
/// <summary>
/// An URL to the listing.
/// </summary>
[JsonPropertyName("listingUrl")]
public string? ListingUrl { get; set; }
/// <summary>
/// Name of the seller who is listing the card.
/// </summary>
public string? Seller { get; set; }
}

View file

@ -3,18 +3,42 @@ using JpnCardsPokemon.Sdk.Utils.JsonConverter;
namespace JpnCardsPokemon.Sdk.Api;
/// <summary>
/// Represents a set object from the web api.
/// </summary>
public class Set
{
/// <summary>
/// The name of the set.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// The internal identification number that the set is given. Used to query for information about this single set or
/// for all cards in this single set.
/// </summary>
public int Id { get; set; }
[JsonPropertyName("source_url")] public string? SourceUrl { get; set; }
/// <summary>
/// The URL to a page which has more information about the set.
/// </summary>
[JsonPropertyName("source_url")]
public string? SourceUrl { get; set; }
[JsonPropertyName("image_url")] public string? ImageUrl { get; set; }
/// <summary>
/// A URL to the official set's image.
/// </summary>
[JsonPropertyName("image_url")]
public string? ImageUrl { get; set; }
/// <summary>
/// The language that the cards in the set are printed in.
/// </summary>
public string? Language { get; set; }
/// <summary>
/// The year the set was released.
/// </summary>
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
[JsonConverter(typeof(NoneIntJsonConverter))] // set hashes in card objects sometimes have "none" as year.
public int Year { get; set; }
@ -22,13 +46,29 @@ public class Set
// TODO: According to documentation the property currently is not supported.
// public DateOnly? Date { get; set; }
[JsonPropertyName("card_count")] public int TotalCardCount { get; set; }
/// <summary>
/// The total number of cards in the set.
/// </summary>
[JsonPropertyName("card_count")]
public int TotalCardCount { get; set; }
/// <summary>
/// The number of cards in the set that is printed on the card. This differs from the set's
/// <see cref="TotalCardCount" /> in sets with Secret Rare cards.
/// </summary>
[JsonPropertyName("printed_count")]
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public int PrintedCardCount { get; set; }
[JsonPropertyName("set_code")] public string? SetCode { get; set; }
/// <summary>
/// The shorthand code for the set.
/// </summary>
[JsonPropertyName("set_code")]
public string? SetCode { get; set; }
/// <summary>
/// A stable id for earch card. Output is an eight digit integer which is unique for each card. While the cards'
/// <see cref="Id" /> may change over time, the uuid should always remain stable and constant.
/// </summary>
public int Uuid { get; set; }
}

View file

@ -12,20 +12,34 @@ using JpnCardsPokemon.Sdk.Utils.QueryFilter;
namespace JpnCardsPokemon.Sdk.Client;
/// <summary>
/// A client to interact with the web api.
/// </summary>
public class ApiClient
{
private readonly HttpClient _client;
#if NETCOREAPP3_1_OR_GREATER
/// <summary>
/// Creates a new instance of the ApiClient.
/// </summary>
/// <param name="handler">Can pass a <see cref="SocketsHttpHandler" /> to use for the internal http client.</param>
public ApiClient(SocketsHttpHandler handler) : this(new HttpClient(handler))
{
}
#endif
/// <summary>
/// Creates a new instance of the ApiClient.
/// </summary>
public ApiClient() : this(new HttpClient())
{
}
/// <summary>
/// Creates a new instance of the ApiClient.
/// </summary>
/// <param name="client">Can pass a http client to use.</param>
public ApiClient(HttpClient client)
{
_client = client;
@ -53,21 +67,45 @@ public class ApiClient
return !string.IsNullOrEmpty(filter) ? $"set/{filter.TrimStart('/')}" : "set";
}
/// <summary>
/// Fetches all <see cref="Set" />.
/// </summary>
/// <returns>Returns an enumerable containing all <see cref="Set" />.</returns>
public async Task<IEnumerable<Set>> FetchSetsAsync()
{
return await FetchInternalAsync<IEnumerable<Set>>(SetQuery(null)) ?? Enumerable.Empty<Set>();
}
/// <summary>
/// Fetches a <see cref="Set" /> by its id.
/// </summary>
/// <param name="id">Id of the <see cref="Set" /> to fetch.</param>
/// <returns>If existing returns the matching <see cref="Set" />.</returns>
public async Task<Set?> FetchSetById(int id)
{
return await FetchInternalAsync<Set>(SetQuery(id.ToString()));
}
/// <summary>
/// Fetches a <see cref="Set" /> by its uuid.
/// </summary>
/// <param name="uuid">Uuid of the <see cref="Set" /> to fetch.</param>
/// <returns>If existing returns the matching <see cref="Set" />.</returns>
public async Task<Set?> FetchSetByUuid(int uuid)
{
return await FetchInternalAsync<Set>(SetQuery($"uuid/{uuid}"));
}
/// <summary>
/// Fetches <see cref="Card" /> from a search query.
/// </summary>
/// <param name="query">The search query.</param>
/// <returns>Returns an enumerable of <see cref="Card" /> matching the <see cref="query" />.</returns>
/// <exception cref="Exception">Thrown if the <see cref="query" /> is empty.</exception>
/// <remarks>
/// At least one filter query must be specified. More information about the query format can be found at
/// https://jpn-cards-site.readthedocs.io/en/latest/api_docs/pokemon/v2/v2_api/#card-queries.
/// </remarks>
public async Task<IEnumerable<Card>> FetchCardsAsync(string query)
{
if (string.IsNullOrWhiteSpace(query))
@ -86,6 +124,12 @@ public class ApiClient
Enumerable.Empty<Card>();
}
/// <summary>
/// Fetches <see cref="Card" /> from a search query.
/// </summary>
/// <param name="filterBuilder">Configured query builder to generate the search query.</param>
/// <returns>Returns an enumerable of <see cref="Card" /> matching the <see cref="query" />.</returns>
/// <remarks> At least one filter must be specified.</remarks>
public async Task<IEnumerable<Card>?> FetchCardsAsync(IQueryFilterBuilder filterBuilder)
{
return await FetchCardsAsync(filterBuilder.BuildQueryString());

View file

@ -10,7 +10,7 @@ namespace JpnCardsPokemon.Sdk.Utils.JsonConverter;
internal class CardPricesJsonConverter : JsonConverter<IEnumerable<CardPrice>>
{
public override IEnumerable<CardPrice>? Read(ref Utf8JsonReader reader, Type typeToConvert,
public override IEnumerable<CardPrice> Read(ref Utf8JsonReader reader, Type typeToConvert,
JsonSerializerOptions options)
{
var resultBucket = new List<CardPrice>();

View file

@ -5,8 +5,13 @@ using System.Text;
namespace JpnCardsPokemon.Sdk.Utils.QueryFilter;
/// <summary>
/// Abstract Implementation of an <see cref="IQueryFilterBuilder" /> which builts the filter string based on
/// <see cref="QueryFilterNameAttribute" /> attributed properties.
/// </summary>
public abstract class AttributedQueryFilterBuilder : IQueryFilterBuilder
{
/// <inheritdoc cref="IQueryFilterBuilder.BuildQueryString" />
public string BuildQueryString()
{
var filterBucket = new List<KeyValuePair<string, string>>();

View file

@ -1,24 +1,72 @@
namespace JpnCardsPokemon.Sdk.Utils.QueryFilter;
using JpnCardsPokemon.Sdk.Api;
namespace JpnCardsPokemon.Sdk.Utils.QueryFilter;
/// <summary>
/// <see cref="IQueryFilterBuilder" /> for <see cref="Card" />.
/// </summary>
public class CardQueryFilterBuilder : AttributedQueryFilterBuilder
{
[QueryFilterName("id")] public int? Id { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.Id" />.
/// </summary>
[QueryFilterName("id")]
public int? Id { get; set; }
[QueryFilterName("name")] public string? Name { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.Name" />.
/// </summary>
/// <remarks>Must match the full name.</remarks>
[QueryFilterName("name")]
public string? Name { get; set; }
[QueryFilterName("set_id")] public int? SetId { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.Set" /> by <see cref="Set.Id" />.
/// </summary>
[QueryFilterName("set_id")]
public int? SetId { get; set; }
[QueryFilterName("illustrator")] public string? Artist { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.Artist" />.
/// </summary>
/// <remarks>Must match the full name.</remarks>
[QueryFilterName("illustrator")]
public string? Artist { get; set; }
[QueryFilterName("p_no")] public string? PrintedNumber { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.PrintedNumber" />.
/// </summary>
[QueryFilterName("p_no")]
public string? PrintedNumber { get; set; }
[QueryFilterName("uuid")] public int? Uuid { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.Uuid" />.
/// </summary>
[QueryFilterName("uuid")]
public int? Uuid { get; set; }
[QueryFilterName("rarity")] public string? Rarity { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.Rarity/>.
///
/// </summary>
[QueryFilterName("rarity")]
public string? Rarity { get; set; }
[QueryFilterName("subtype")] public string? Subtype { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.Subtypes" />.
/// </summary>
[QueryFilterName("subtype")]
public string? Subtype { get; set; }
[QueryFilterName("type")] public string? Type { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.Types" />.
/// </summary>
[QueryFilterName("type")]
public string? Type { get; set; }
[QueryFilterName("set_code")] public string? SetCode { get; set; }
/// <summary>
/// Sets a filter for the <see cref="Card.Set" /> by <see cref="Set.SetCode" />.
/// </summary>
[QueryFilterName("set_code")]
public string? SetCode { get; set; }
}

View file

@ -1,6 +1,13 @@
namespace JpnCardsPokemon.Sdk.Utils.QueryFilter;
/// <summary>
/// Defines an interface for a filter builder.
/// </summary>
public interface IQueryFilterBuilder
{
/// <summary>
/// Builds the query filter to use for the api request.
/// </summary>
/// <returns>Returns the built query filter.</returns>
string BuildQueryString();
}

View file

@ -2,17 +2,30 @@
namespace JpnCardsPokemon.Sdk.Utils.QueryFilter;
/// <summary>
/// Attribute which can be used to mark a property as a filter for the <see cref="AttributedQueryFilterBuilder" />.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class QueryFilterNameAttribute : Attribute
{
/// <summary>
/// Creates a new query filter attribute with a custom filter name.
/// </summary>
/// <param name="paramName">Custom filter name for the web request.</param>
public QueryFilterNameAttribute(string? paramName)
{
ParamName = paramName;
}
/// <summary>
/// Creates a new query filter attribute.
/// </summary>
public QueryFilterNameAttribute() : this(null)
{
}
/// <summary>
/// Filter name for the web api.
/// </summary>
public string? ParamName { get; set; }
}