Skip to content

Commit 4740803

Browse files
authored
fix compilation failure in helpers/message & tests/testHelpers.nim (#136)
* fix missing import and mctbutton in helper test suite * fix message/edit helper * revert s symbol check proc in macros.nim
1 parent 86362d7 commit 4740803

File tree

3 files changed

+145
-147
lines changed

3 files changed

+145
-147
lines changed

dimscord/helpers/message.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ template editMessage*(c: SomeChannel, m: Message;
6565
components
6666
)
6767

68-
proc edit*(m: Message;
68+
template edit*(m: Message;
6969
content = "";
7070
embeds: seq[Embed] = @[];
7171
attachments: seq[Attachment] = @[];
7272
components: seq[MessageComponent] = @[];
7373
files: seq[DiscordFile] = @[];
7474
tts = false;
75-
flags = none set[MessageFlags]): Future[Message] {.async.} =
75+
flags = none set[MessageFlags]): Future[Message] =
7676
## Edits a Message.
7777

7878
# getMessage(getClient.shards[0].cache.gchannel(m), "123")

dimscord/objects/macros.nim

Lines changed: 141 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,141 @@
1-
import std/[macros, macrocache], typedefs
2-
3-
#const clientCache = CacheSeq"dimscord.client"
4-
5-
macro keyCheckOptInt*(obj: typed, obj2: typed,
6-
lits: varargs[untyped]): untyped =
7-
result = newStmtList()
8-
for lit in lits:
9-
let fieldName = lit.strVal
10-
result.add quote do:
11-
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
12-
`obj2`.`lit` = some `obj`[`fieldName`].getInt
13-
14-
macro keyCheckOptBool*(obj: typed, obj2: typed,
15-
lits: varargs[untyped]): untyped =
16-
result = newStmtList()
17-
for lit in lits:
18-
let fieldName = lit.strVal
19-
result.add quote do:
20-
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
21-
`obj2`.`lit` = some `obj`[`fieldName`].getBool
22-
23-
macro keyCheckBool*(obj: typed, obj2: typed,
24-
lits: varargs[untyped]): untyped =
25-
result = newStmtList()
26-
for lit in lits:
27-
let fieldName = lit.strVal
28-
result.add quote do:
29-
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
30-
`obj2`.`lit` = `obj`[`fieldName`].getBool
31-
32-
macro keyCheckOptStr*(obj: typed, obj2: typed,
33-
lits: varargs[untyped]): untyped =
34-
result = newStmtList()
35-
for lit in lits:
36-
let fieldName = lit.strVal
37-
result.add quote do:
38-
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
39-
`obj2`.`lit` = some `obj`[`fieldName`].getStr
40-
41-
macro keyCheckStr*(obj: typed, obj2: typed,
42-
lits: varargs[untyped]): untyped =
43-
result = newStmtList()
44-
for lit in lits:
45-
let fieldName = lit.strVal
46-
result.add quote do:
47-
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
48-
`obj2`.`lit` = `obj`[`fieldName`].getStr
49-
50-
macro loadOpt*(obj: typed, lits: varargs[untyped]): untyped =
51-
result = newStmtList()
52-
for lit in lits:
53-
let fieldName = lit.strVal
54-
result.add quote do:
55-
if `lit`.isSome:
56-
var value = %*get(`lit`)
57-
when `lit` is Option[int]:
58-
if `lit`.get == -1: value = newJNull()
59-
when `lit` is Option[string]:
60-
if `lit`.get == "": value = newJNull()
61-
when `lit` is Option[enum]:
62-
value = %*(ord get(`lit`))
63-
64-
`obj`[`fieldName`] = value
65-
66-
macro loadOpts*(res, parent: typed, lits: varargs[untyped]): untyped =
67-
result = newStmtList()
68-
for lit in lits:
69-
let fieldName = lit.strVal
70-
result.add quote do:
71-
if `parent`.`lit`.isSome:
72-
`res`[`fieldName`] = %*get(`parent`.`lit`)
73-
74-
macro loadNullableOptStr*(obj: typed, lits: varargs[untyped]): untyped =
75-
result = newStmtList()
76-
for lit in lits:
77-
let fieldName = lit.strVal
78-
result.add quote do:
79-
if `lit`.isSome and get(`lit`) == "":
80-
`obj`[`fieldName`] = newJNull()
81-
82-
macro loadNullableOptInt*(obj: typed, lits: varargs[untyped]): untyped =
83-
result = newStmtList()
84-
for lit in lits:
85-
let fieldName = lit.strVal
86-
result.add quote do:
87-
if `lit`.isSome and get(`lit`) == -1:
88-
`obj`[`fieldName`] = newJNull()
89-
90-
macro optionIf*(check: typed): untyped =
91-
## Runs `check` to see if a variable is considered empty
92-
## - if check is true, then it returns None[T]
93-
## - if check is false, then it returns some(variable)
94-
## not very robust but supports basics like calls, field access
95-
expectKind check, nnkInfix
96-
let symbol = case check[1].kind:
97-
of nnkDotExpr: check[1][1]
98-
else: check[1]
99-
let
100-
variable = check[1]
101-
varType = ident $symbol.getType()
102-
103-
result = quote do:
104-
if `check`: none `varType` else: some (`variable`)
105-
106-
macro mainClient*(x: typed) =
107-
## Registers a DiscordClient for helper templates
108-
## Usage: `let discord {.mainClient.} = newDiscordClient("TOKEN")`
109-
let tname = ident("dimscordPrivateClient")
110-
var vname: NimNode
111-
if (x.kind == nnkLetSection) or (x.kind == nnkVarSection):
112-
vname = x[0][0]
113-
else:
114-
# TODO: check for `newDiscordClient` presence
115-
error("Invalid usage, macro expects a let or var statement")
116-
result = newStmtList()
117-
result.add(x)
118-
result.add(quote do:
119-
template `tname`*(): DiscordClient {.dirty.} =
120-
`vname`
121-
)
122-
123-
proc sCheck(): bool =
124-
when declared(s): s is Shard
125-
126-
template getClient*: DiscordClient =
127-
## Gets registered client or shard client
128-
when declared(dimscordPrivateClient):
129-
var dc {.cursor.} = dimscordPrivateClient() # note: is safe in async code ?
130-
when defined(dimscordDebug):
131-
if dc.isNil:
132-
raise (ref AccessViolationDefect)(
133-
msg: "Client is nil: Check client initialization"
134-
)
135-
dc
136-
elif sCheck():
137-
when defined(dimscordDebug):
138-
if s.client.isNil:
139-
raise (ref AccessViolationDefect)(
140-
msg: "Client is nil: Check shard initialization"
141-
)
142-
s.client
143-
else:
144-
{.error: "No client found. Use `mainClient` or ensure 's' Shard exists".}
1+
import std/[macros, macrocache], typedefs
2+
3+
#const clientCache = CacheSeq"dimscord.client"
4+
5+
macro keyCheckOptInt*(obj: typed, obj2: typed,
6+
lits: varargs[untyped]): untyped =
7+
result = newStmtList()
8+
for lit in lits:
9+
let fieldName = lit.strVal
10+
result.add quote do:
11+
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
12+
`obj2`.`lit` = some `obj`[`fieldName`].getInt
13+
14+
macro keyCheckOptBool*(obj: typed, obj2: typed,
15+
lits: varargs[untyped]): untyped =
16+
result = newStmtList()
17+
for lit in lits:
18+
let fieldName = lit.strVal
19+
result.add quote do:
20+
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
21+
`obj2`.`lit` = some `obj`[`fieldName`].getBool
22+
23+
macro keyCheckBool*(obj: typed, obj2: typed,
24+
lits: varargs[untyped]): untyped =
25+
result = newStmtList()
26+
for lit in lits:
27+
let fieldName = lit.strVal
28+
result.add quote do:
29+
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
30+
`obj2`.`lit` = `obj`[`fieldName`].getBool
31+
32+
macro keyCheckOptStr*(obj: typed, obj2: typed,
33+
lits: varargs[untyped]): untyped =
34+
result = newStmtList()
35+
for lit in lits:
36+
let fieldName = lit.strVal
37+
result.add quote do:
38+
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
39+
`obj2`.`lit` = some `obj`[`fieldName`].getStr
40+
41+
macro keyCheckStr*(obj: typed, obj2: typed,
42+
lits: varargs[untyped]): untyped =
43+
result = newStmtList()
44+
for lit in lits:
45+
let fieldName = lit.strVal
46+
result.add quote do:
47+
if `fieldName` in `obj` and `obj`[`fieldName`].kind != JNull:
48+
`obj2`.`lit` = `obj`[`fieldName`].getStr
49+
50+
macro loadOpt*(obj: typed, lits: varargs[untyped]): untyped =
51+
result = newStmtList()
52+
for lit in lits:
53+
let fieldName = lit.strVal
54+
result.add quote do:
55+
if `lit`.isSome:
56+
var value = %*get(`lit`)
57+
when `lit` is Option[int]:
58+
if `lit`.get == -1: value = newJNull()
59+
when `lit` is Option[string]:
60+
if `lit`.get == "": value = newJNull()
61+
when `lit` is Option[enum]:
62+
value = %*(ord get(`lit`))
63+
64+
`obj`[`fieldName`] = value
65+
66+
macro loadOpts*(res, parent: typed, lits: varargs[untyped]): untyped =
67+
result = newStmtList()
68+
for lit in lits:
69+
let fieldName = lit.strVal
70+
result.add quote do:
71+
if `parent`.`lit`.isSome:
72+
`res`[`fieldName`] = %*get(`parent`.`lit`)
73+
74+
macro loadNullableOptStr*(obj: typed, lits: varargs[untyped]): untyped =
75+
result = newStmtList()
76+
for lit in lits:
77+
let fieldName = lit.strVal
78+
result.add quote do:
79+
if `lit`.isSome and get(`lit`) == "":
80+
`obj`[`fieldName`] = newJNull()
81+
82+
macro loadNullableOptInt*(obj: typed, lits: varargs[untyped]): untyped =
83+
result = newStmtList()
84+
for lit in lits:
85+
let fieldName = lit.strVal
86+
result.add quote do:
87+
if `lit`.isSome and get(`lit`) == -1:
88+
`obj`[`fieldName`] = newJNull()
89+
90+
macro optionIf*(check: typed): untyped =
91+
## Runs `check` to see if a variable is considered empty
92+
## - if check is true, then it returns None[T]
93+
## - if check is false, then it returns some(variable)
94+
## not very robust but supports basics like calls, field access
95+
expectKind check, nnkInfix
96+
let symbol = case check[1].kind:
97+
of nnkDotExpr: check[1][1]
98+
else: check[1]
99+
let
100+
variable = check[1]
101+
varType = ident $symbol.getType()
102+
103+
result = quote do:
104+
if `check`: none `varType` else: some (`variable`)
105+
106+
macro mainClient*(x: typed) =
107+
## Registers a DiscordClient for helper templates
108+
## Usage: `let discord {.mainClient.} = newDiscordClient("TOKEN")`
109+
let tname = ident("dimscordPrivateClient")
110+
var vname: NimNode
111+
if (x.kind == nnkLetSection) or (x.kind == nnkVarSection):
112+
vname = x[0][0]
113+
else:
114+
# TODO: check for `newDiscordClient` presence
115+
error("Invalid usage, macro expects a let or var statement")
116+
result = newStmtList()
117+
result.add(x)
118+
result.add(quote do:
119+
template `tname`*(): DiscordClient {.dirty.} =
120+
`vname`
121+
)
122+
123+
template getClient*: DiscordClient =
124+
## Gets registered client or shard client
125+
when declared(dimscordPrivateClient):
126+
var dc {.cursor.} = dimscordPrivateClient() # note: is safe in async code ?
127+
when defined(dimscordDebug):
128+
if dc.isNil:
129+
raise (ref AccessViolationDefect)(
130+
msg: "Client is nil: Check client initialization"
131+
)
132+
dc
133+
elif declared(s) and (s is Shard):
134+
when defined(dimscordDebug):
135+
if s.client.isNil:
136+
raise (ref AccessViolationDefect)(
137+
msg: "Client is nil: Check shard initialization"
138+
)
139+
s.client
140+
else:
141+
{.error: "No client found. Use `mainClient` or ensure 's' Shard exists".}

tests/testHelpers.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import unittest
33
import asyncdispatch
44
import options, tables
55
import json
6+
import std/setutils
67
import ../dimscord/objects
78
import ../dimscord/constants
89
import ../dimscord/restapi
@@ -18,7 +19,7 @@ let mockSeqString = @["mock1", "mock2"]
1819
let mockTableString = {"en-US": some("mock_value")}.toTable()
1920
let mockEmbed = Embed(title: some("Test Embed"))
2021
let mockAttachment = Attachment(id: "123", filename: "test.txt")
21-
let mockComponent = MessageComponent(kind: MessageComponentType.Button, custom_id: some("mock_button"))
22+
let mockComponent = MessageComponent(kind: MessageComponentType.mctButton, custom_id: some("mock_button"))
2223
let mockFile = DiscordFile(name: "test.txt", body: "")
2324
let mockAllowedMentions = AllowedMentions(parse: @[])
2425
let mockPermObj = PermObj(allowed: {}, denied: {})

0 commit comments

Comments
 (0)