disable Nimble dependencies for appveyor
This commit is contained in:
parent
bf0993c835
commit
d2208091fa
43 changed files with 27230 additions and 7 deletions
141
tests/deps/jester-#head/jester/patterns.nim
Normal file
141
tests/deps/jester-#head/jester/patterns.nim
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
# Copyright (C) 2012-2018 Dominik Picheta
|
||||
# MIT License - Look at license.txt for details.
|
||||
import parseutils, tables
|
||||
type
|
||||
NodeType* = enum
|
||||
NodeText, NodeField
|
||||
Node* = object
|
||||
typ*: NodeType
|
||||
text*: string
|
||||
optional*: bool
|
||||
|
||||
Pattern* = seq[Node]
|
||||
|
||||
#/show/@id/?
|
||||
proc parsePattern*(pattern: string): Pattern =
|
||||
result = @[]
|
||||
template addNode(result: var Pattern, theT: NodeType, theText: string,
|
||||
isOptional: bool): typed =
|
||||
block:
|
||||
var newNode: Node
|
||||
newNode.typ = theT
|
||||
newNode.text = theText
|
||||
newNode.optional = isOptional
|
||||
result.add(newNode)
|
||||
|
||||
template `{}`(s: string, i: int): char =
|
||||
if i >= len(s):
|
||||
'\0'
|
||||
else:
|
||||
s[i]
|
||||
|
||||
var i = 0
|
||||
var text = ""
|
||||
while i < pattern.len():
|
||||
case pattern[i]
|
||||
of '@':
|
||||
# Add the stored text.
|
||||
if text != "":
|
||||
result.addNode(NodeText, text, false)
|
||||
text = ""
|
||||
# Parse named parameter.
|
||||
inc(i) # Skip @
|
||||
var nparam = ""
|
||||
i += pattern.parseUntil(nparam, {'/', '?'}, i)
|
||||
var optional = pattern{i} == '?'
|
||||
result.addNode(NodeField, nparam, optional)
|
||||
if pattern{i} == '?': inc(i) # Only skip ?. / should not be skipped.
|
||||
of '?':
|
||||
var optionalChar = text[^1]
|
||||
setLen(text, text.len-1) # Truncate ``text``.
|
||||
# Add the stored text.
|
||||
if text != "":
|
||||
result.addNode(NodeText, text, false)
|
||||
text = ""
|
||||
# Add optional char.
|
||||
inc(i) # Skip ?
|
||||
result.addNode(NodeText, $optionalChar, true)
|
||||
of '\\':
|
||||
inc i # Skip \
|
||||
if pattern[i] notin {'?', '@', '\\'}:
|
||||
raise newException(ValueError,
|
||||
"This character does not require escaping: " & pattern[i])
|
||||
text.add(pattern{i})
|
||||
inc i # Skip ``pattern[i]``
|
||||
else:
|
||||
text.add(pattern{i})
|
||||
inc(i)
|
||||
|
||||
if text != "":
|
||||
result.addNode(NodeText, text, false)
|
||||
|
||||
proc findNextText(pattern: Pattern, i: int, toNode: var Node): bool =
|
||||
## Finds the next NodeText in the pattern, starts looking from ``i``.
|
||||
result = false
|
||||
for n in i..pattern.len()-1:
|
||||
if pattern[n].typ == NodeText:
|
||||
toNode = pattern[n]
|
||||
return true
|
||||
|
||||
proc check(n: Node, s: string, i: int): bool =
|
||||
let cutTo = (n.text.len-1)+i
|
||||
if cutTo > s.len-1: return false
|
||||
return s.substr(i, cutTo) == n.text
|
||||
|
||||
proc match*(pattern: Pattern, s: string):
|
||||
tuple[matched: bool, params: Table[string, string]] =
|
||||
var i = 0 # Location in ``s``.
|
||||
|
||||
result.matched = true
|
||||
result.params = initTable[string, string]()
|
||||
|
||||
for ncount, node in pattern:
|
||||
case node.typ
|
||||
of NodeText:
|
||||
if node.optional:
|
||||
if check(node, s, i):
|
||||
inc(i, node.text.len) # Skip over this optional character.
|
||||
else:
|
||||
# If it's not there, we have nothing to do. It's optional after all.
|
||||
discard
|
||||
else:
|
||||
if check(node, s, i):
|
||||
inc(i, node.text.len) # Skip over this
|
||||
else:
|
||||
# No match.
|
||||
result.matched = false
|
||||
return
|
||||
of NodeField:
|
||||
var nextTxtNode: Node
|
||||
var stopChar = '/'
|
||||
if findNextText(pattern, ncount, nextTxtNode):
|
||||
stopChar = nextTxtNode.text[0]
|
||||
var matchNamed = ""
|
||||
i += s.parseUntil(matchNamed, stopChar, i)
|
||||
result.params[node.text] = matchNamed
|
||||
if matchNamed == "" and not node.optional:
|
||||
result.matched = false
|
||||
return
|
||||
|
||||
if s.len != i:
|
||||
result.matched = false
|
||||
|
||||
when isMainModule:
|
||||
let f = parsePattern("/show/@id/test/@show?/?")
|
||||
doAssert match(f, "/show/12/test/hallo/").matched
|
||||
doAssert match(f, "/show/2131726/test/jjjuuwąąss").matched
|
||||
doAssert(not match(f, "/").matched)
|
||||
doAssert(not match(f, "/show//test//").matched)
|
||||
doAssert(match(f, "/show/asd/test//").matched)
|
||||
doAssert(not match(f, "/show/asd/asd/test/jjj/").matched)
|
||||
doAssert(match(f, "/show/@łę¶ŧ←/test/asd/").params["id"] == "@łę¶ŧ←")
|
||||
|
||||
let f2 = parsePattern("/test42/somefile.?@ext?/?")
|
||||
doAssert(match(f2, "/test42/somefile/").params["ext"] == "")
|
||||
doAssert(match(f2, "/test42/somefile.txt").params["ext"] == "txt")
|
||||
doAssert(match(f2, "/test42/somefile.txt/").params["ext"] == "txt")
|
||||
|
||||
let f3 = parsePattern(r"/test32/\@\\\??")
|
||||
doAssert(match(f3, r"/test32/@\").matched)
|
||||
doAssert(not match(f3, r"/test32/@\\").matched)
|
||||
doAssert(match(f3, r"/test32/@\?").matched)
|
||||
Loading…
Add table
Add a link
Reference in a new issue