diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-08-10 12:06:16 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-08-10 12:06:16 +0200 |
commit | 404de2f23e931f922f283faa6d3491bfe3c0e68e (patch) | |
tree | 79ed71c485de952680a02a653f81ce00cc4da531 /lib | |
parent | 1d78ba64b4761de88817a2e5748a456679cb2bab (diff) | |
parent | 43f634db8dfac4fb13c8454958d35e776410dac1 (diff) | |
download | Nim-404de2f23e931f922f283faa6d3491bfe3c0e68e.tar.gz |
Merge branch 'devel' into araq-misc
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/collections/sequtils.nim | 11 | ||||
-rw-r--r-- | lib/pure/httpclient.nim | 15 | ||||
-rw-r--r-- | lib/pure/sugar.nim | 38 | ||||
-rw-r--r-- | lib/system/channels.nim | 2 |
4 files changed, 60 insertions, 6 deletions
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index 8f81fe4f5..99ce91979 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -676,8 +676,8 @@ template mapIt*(s, op: untyped): untyped = var it{.inject.}: type(items(s)); op)) var result: seq[outType] - evalOnce(t, s) - when compiles(t.len): + when compiles(s.len): + evalOnce(t, s) var i = 0 result = newSeq[outType](t.len) for it {.inject.} in t: @@ -685,7 +685,7 @@ template mapIt*(s, op: untyped): untyped = i += 1 else: result = @[] - for it {.inject.} in t: + for it {.inject.} in s: result.add(op) result @@ -1071,5 +1071,10 @@ when isMainModule: proc foo(x: openArray[int]): seq[int] = x.mapIt(it + 1) doAssert foo([1,2,3]) == @[2,3,4] + block: # mapIt with invalid RHS for `let` (#8566) + type X = enum + A, B + doAssert mapIt(X, $it) == @["A", "B"] + when not defined(testing): echo "Finished doc tests" diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 8b4fb0f8c..72de72718 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -807,6 +807,7 @@ type lastProgressReport: float when SocketType is AsyncSocket: bodyStream: FutureStream[string] + parseBodyFut: Future[void] else: bodyStream: Stream getBody: bool ## When `false`, the body is never read in requestAux. @@ -1066,10 +1067,14 @@ proc parseResponse(client: HttpClient | AsyncHttpClient, if getBody: when client is HttpClient: client.bodyStream = newStringStream() + result.bodyStream = client.bodyStream + parseBody(client, result.headers, result.version) else: client.bodyStream = newFutureStream[string]("parseResponse") - await parseBody(client, result.headers, result.version) - result.bodyStream = client.bodyStream + result.bodyStream = client.bodyStream + assert(client.parseBodyFut.isNil or client.parseBodyFut.finished) + client.parseBodyFut = parseBody(client, result.headers, result.version) + # do not wait here for the body request to complete proc newConnection(client: HttpClient | AsyncHttpClient, url: Uri) {.multisync.} = @@ -1159,6 +1164,12 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string, # Helper that actually makes the request. Does not handle redirects. let requestUrl = parseUri(url) + when client is AsyncHttpClient: + if not client.parseBodyFut.isNil: + # let the current operation finish before making another request + await client.parseBodyFut + client.parseBodyFut = nil + await newConnection(client, requestUrl) let effectiveHeaders = client.headers.override(headers) diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim index 258b40191..8ded552d9 100644 --- a/lib/pure/sugar.nim +++ b/lib/pure/sugar.nim @@ -198,3 +198,41 @@ macro dump*(x: typed): untyped = let r = quote do: debugEcho `s`, " = ", `x` return r + +# TODO: consider exporting this in macros.nim +proc freshIdentNodes(ast: NimNode): NimNode = + # Replace NimIdent and NimSym by a fresh ident node + # see also https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458 + proc inspect(node: NimNode): NimNode = + case node.kind: + of nnkIdent, nnkSym: + result = ident($node) + of nnkEmpty, nnkLiterals: + result = node + else: + result = node.kind.newTree() + for child in node: + result.add inspect(child) + result = inspect(ast) + +macro distinctBase*(T: typedesc): untyped = + ## reverses ``type T = distinct A``; works recursively. + runnableExamples: + type T = distinct int + doAssert distinctBase(T) is int + doAssert: not compiles(distinctBase(int)) + type T2 = distinct T + doAssert distinctBase(T2) is int + + let typeNode = getTypeImpl(T) + expectKind(typeNode, nnkBracketExpr) + if typeNode[0].typeKind != ntyTypeDesc: + error "expected typeDesc, got " & $typeNode[0] + var typeSym = typeNode[1] + typeSym = getTypeImpl(typeSym) + if typeSym.typeKind != ntyDistinct: + error "type is not distinct" + typeSym = typeSym[0] + while typeSym.typeKind == ntyDistinct: + typeSym = getTypeImpl(typeSym)[0] + typeSym.freshIdentNodes diff --git a/lib/system/channels.nim b/lib/system/channels.nim index 254b87dfc..14d3a3005 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -233,7 +233,7 @@ proc send*[TMsg](c: var Channel[TMsg], msg: TMsg) {.inline.} = proc trySend*[TMsg](c: var Channel[TMsg], msg: TMsg): bool {.inline.} = ## Tries to send a message to a thread. `msg` is deeply copied. Doesn't block. ## Returns `false` if the message was not sent because number of pending items - ## in the cannel exceeded `maxItems`. + ## in the channel exceeded `maxItems`. sendImpl(cast[PRawChannel](addr c), cast[PNimType](getTypeInfo(msg)), unsafeAddr(msg), true) proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) = |