Skip to content

Commit

Permalink
make sorting order deterministic
Browse files Browse the repository at this point in the history
  • Loading branch information
froehlichA committed Apr 17, 2022
1 parent f0c6a5e commit 2210ae0
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
17 changes: 14 additions & 3 deletions src/api/cfclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
## Docs for the official API are available at https://docs.curseforge.com.
## Requests to the proxy stay the same, except the base URL is switched out.

import std/[asyncdispatch, json, options, sequtils, strutils, sugar]
import std/[asyncdispatch, json, options, sequtils, strutils, sugar, tables]
import uri except Url
import cfcore, http

Expand All @@ -22,6 +22,17 @@ const
type
CfClientError* = object of HttpRequestError

proc sortTo[T, X](s: seq[T], x: seq[X], pred: proc (x: T): X): seq[T] =
## sort `s` so that the order of its items matches `x`.
## `pred` should be a function that returns a unique value to which `s` is sorted.
assert s.len == x.len

var table = initTable[X, T]()
for sItem in s:
table[pred(sItem)] = sItem
for xItem in x:
result.add(table[xItem])

proc fetchAddonsByQuery*(query: string, category: Option[CfAddonGameCategory]): Future[seq[CfAddon]] {.async.} =
## retrieves all addons that match the given `query` search and `category`.
let encodedQuery = encodeUrl(query, usePlus = false)
Expand Down Expand Up @@ -66,7 +77,7 @@ proc fetchAddons*(projectIds: seq[int], chunk = true): Future[seq[CfAddon]] {.as
let addons = post(url.Url, $body).await.parseJson["data"].addonsFromForgeSvc
if addons.len != projectIds.len:
raise newException(CfClientError, "one of the addons of project ids '" & $projectIds & "' was not found.")
return addons
return addons.sortTo(projectIds, (x) => x.projectId)
except HttpRequestError:
let futures: seq[Future[CfAddon]] = collect:
for projectId in projectIds:
Expand Down Expand Up @@ -101,7 +112,7 @@ proc fetchAddonFiles*(fileIds: seq[int]): Future[seq[CfAddonFile]] {.async.} =
let addonFiles = post(url.Url, $body).await.parseJson["data"].addonFilesFromForgeSvc
if addonFiles.len != fileIds.len:
raise newException(CfClientError, "one of the addon files of file ids '" & $fileIds & "' was not found.")
return addonFiles
return addonFiles.sortTo(fileIds, (x) => x.fileId)
except HttpRequestError:
raise newException(CfClientError, "one of the addon files of file ids '" & $fileIds & "' was not found.")

Expand Down
8 changes: 4 additions & 4 deletions tests/api/tcfclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ asyncBlock: # fetch mod by non-existing id

asyncBlock: # fetch mods by id
let mcMods = await fetchAddons(@[220318, 238222])
doAssert mcMods.any((x) => x.projectId == 220318)
doAssert mcMods.any((x) => x.projectId == 238222)
doAssert mcMods[0].projectId == 220318
doAssert mcMods[1].projectId == 238222

asyncBlock: # fetch mods by non-existing id
doAssertRaises(CfClientError):
Expand Down Expand Up @@ -59,8 +59,8 @@ asyncBlock: # fetch mod files by non-existing project id

asyncBlock: # fetch mod files by file ids
let modFiles = await fetchAddonFiles(@[2992184, 3098571])
doAssert modFiles.any((x) => x.fileId == 2992184)
doAssert modFiles.any((x) => x.fileId == 3098571)
doAssert modFiles[0].fileId == 2992184
doAssert modFiles[1].fileId == 3098571

asyncBlock: # fetch mod files by non-existing file ids
doAssertRaises(CfClientError):
Expand Down

0 comments on commit 2210ae0

Please sign in to comment.