Skip to content

Commit

Permalink
Merge pull request #114 from Atlas-Rhythm/fix/link-serialization
Browse files Browse the repository at this point in the history
Fixed and improved link serialization
  • Loading branch information
Auros committed Jul 26, 2023
2 parents 1eba85d + 70388da commit e41ef1f
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/Hive.Tests/Endpoints/ModsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ public async Task EditModStandard()
ConflictsWith = new ModReference[]
{
new("TrickSaber", new VersionRange("^2.5.1")) // Add new conflict
}.ToImmutableList()
}.ToImmutableList(),
Links = Array.Empty<Link>().ToImmutableList()
};

await using var stringStream = TestHelpers.GenerateStreamFromString(JsonSerializer.Serialize(identifier));
Expand Down
2 changes: 1 addition & 1 deletion src/Hive.Tests/Endpoints/UploadController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public async Task ValidUploadProcess()
Name = "Test Mod 1",
Description = "The first uploaded test mod"
},
Links = ImmutableList.Create(("project-home", "https://test-mod.bsmg.wiki/")),
Links = ImmutableList.Create(new Link("project-home", new Uri("https://test-mod.bsmg.wiki/"))),
ChannelName = "newly-uploaded",
SupportedGameVersions = ImmutableList.Create("1.12.1", "1.13.0"),
Dependencies = ImmutableList.Create(new ModReference("bsipa", new VersionRange("^4.0.0"))),
Expand Down
2 changes: 1 addition & 1 deletion src/Hive/Controllers/UploadController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ public async Task<ActionResult<UploadResult>> CompleteUpload([FromForm] string f
Uploader = user,
Dependencies = finalMetadata.Dependencies?.ToList() ?? new(), // if deps is null, default to empty list (it's allowed)
Conflicts = finalMetadata.ConflictsWith?.ToList() ?? new(), // same as above
Links = finalMetadata.Links?.Select(t => (t.Item1, new Uri(t.Item2))).ToList() ?? new(), // defaults to empty list
Links = finalMetadata.Links?.ToList() ?? new(), // defaults to empty list
Authors = new List<User>(), // both of these default to empty lists
Contributors = new List<User>(),
};
Expand Down
9 changes: 5 additions & 4 deletions src/Hive/Graphing/Types/LinkType.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using GraphQL.Types;
using Hive.Models;

namespace Hive.Graphing.Types
{
/// <summary>
/// The GQL representation of a link on a <see cref="Models.Mod"/>. Specifically from <seealso cref="Models.Mod.Links"/>.
/// </summary>
public class LinkType : ObjectGraphType<(string, Uri)>
public class LinkType : ObjectGraphType<Link>
{
/// <summary>
/// Setup a LinkType for GQL.
Expand All @@ -20,14 +21,14 @@ public LinkType(IEnumerable<ICustomHiveGraph<LinkType>> customGraphs)
Name = "Link";
Description = Resources.GraphQL.Link;

_ = Field(l => l.Item1)
_ = Field(l => l.Name)
.Name("name")
.Description(Resources.GraphQL.Link_Name);

_ = Field<StringGraphType>(
"url",
"location",
Resources.GraphQL.Link_URL,
resolve: context => context.Source.Item2.ToString()
resolve: context => context.Source.Location.ToString()
);

foreach (var graph in customGraphs)
Expand Down
60 changes: 60 additions & 0 deletions src/Hive/Models/Link.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Text.Json.Serialization;

namespace Hive.Models;

/// <summary>
/// Represented a named link, something with a readable identifier and a Uri location
/// </summary>
public readonly struct Link : IEquatable<Link>
{
/// <summary>
/// The name of the link.
/// </summary>
public string Name { get; } = string.Empty;

/// <summary>
/// The location (uRI) of the link.
/// </summary>
public Uri Location { get; } = null!;

/// <summary>
/// Construct a Link object with a name and Uri
/// </summary>
/// <param name="name"></param>
/// <param name="location"></param>
[JsonConstructor]
public Link(string name, Uri location)
{
Name = name;
Location = location;
}

/// <inheritdoc/>
public override string ToString() => $"({Name})[{Location}]";

/// <inheritdoc/>
public bool Equals(Link other) => Name == other.Name && Location.Equals(other.Location);

/// <inheritdoc/>
public override bool Equals(object? obj) => obj is Link other && Equals(other);

/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(Name, Location);

/// <summary>
/// Equals operator
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator ==(Link left, Link right) => left.Equals(right);

/// <summary>
/// Not equals operator
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator !=(Link left, Link right) => !left.Equals(right);
}
2 changes: 1 addition & 1 deletion src/Hive/Models/Mod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public class Mod
/// </summary>
[Column(TypeName = "jsonb")] // use jsonb here because that will let the db handle it sanely
[SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "EF wants a setter")]
public IList<(string Name, Uri Url)> Links { get; set; } = new List<(string, Uri)>();
public IList<Link> Links { get; set; } = new List<Link>();

/// <summary>
/// The download link of the mod.
Expand Down
6 changes: 3 additions & 3 deletions src/Hive/Models/Serialized/SerializedMod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ public record SerializedMod
public ImmutableList<string> SupportedGameVersions { get; init; } = null!;

/// <summary>
/// The links provided of the <see cref="Mod"/>, with the left hand side as the name and the right hand side as the url.
/// The links provided of the <see cref="Mod"/>.
/// </summary>
public ImmutableList<(string, string)> Links { get; init; } = null!;
public ImmutableList<Link> Links { get; init; } = null!;

/// <summary>
/// The dependencies (a list of <see cref="ModReference"/> objects) of the <see cref="Mod"/>.
Expand Down Expand Up @@ -117,7 +117,7 @@ public static SerializedMod Serialize([DisallowNull] Mod toSerialize, LocalizedM
Authors = toSerialize.Authors.Select(x => x.Username).ToImmutableList(),
Contributors = toSerialize.Contributors.Select(x => x.Username).ToImmutableList(),
SupportedGameVersions = toSerialize.SupportedVersions.Select(x => x.Name!).ToImmutableList(),
Links = toSerialize.Links.Select(x => (x.Name, x.Url.ToString()))!.ToImmutableList(),
Links = toSerialize.Links.ToImmutableList(),
Dependencies = toSerialize.Dependencies.ToImmutableList(),
ConflictsWith = toSerialize.Conflicts.ToImmutableList()
};
Expand Down
5 changes: 5 additions & 0 deletions src/Hive/Models/Serialized/SerializedModUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,10 @@ public class SerializedModUpdate
/// The conflicts (a list of <see cref="ModReference"/> objects) of the <see cref="Mod"/>
/// </summary>
public ImmutableList<ModReference> ConflictsWith { get; init; } = null!;

/// <summary>
/// The links of the <see cref="Mod"/>
/// </summary>
public ImmutableList<Link> Links { get; init; } = null!;
}
}
3 changes: 2 additions & 1 deletion src/Hive/Services/Common/ModService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ public async Task<HiveObjectQuery<Mod>> UpdateMod(User? user, SerializedModUpdat

var versions = await context.GameVersions.AsTracking().Where(g => update.SupportedGameVersions.Contains(g.Name)).ToArrayAsync().ConfigureAwait(false);

databaseMod.Links = update.Links;
databaseMod.SupportedVersions = versions;
databaseMod.Dependencies = update.Dependencies;
databaseMod.Conflicts = update.ConflictsWith;
Expand All @@ -345,7 +346,7 @@ private async Task<IEnumerable<Mod>> GetFilteredModList(string[]? channelIds, st
var mods = CreateModQuery();

// Perform various filtering on our mods
if (channelIds != null && channelIds.Length > 0)
if (channelIds is { Length: > 0 })
{
var filteredChannels = context.Channels.Where(c => channelIds.Contains(c.Name));

Expand Down

0 comments on commit e41ef1f

Please sign in to comment.