Add operators for arithmetic predicates

This commit is contained in:
Fabrice Reix 2021-06-19 08:52:45 +02:00
parent e30548b18c
commit 8844c1e60a
19 changed files with 550 additions and 183 deletions

View File

@ -1 +1 @@
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/assert-header</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line"><span class="string">Content-Type</span><span>:</span> <span class="string">text/html; charset=utf-8</span></span><span class="line"><span class="string">Set-Cookie</span><span>:</span> <span class="string">cookie1=value1; Path=/</span></span><span class="line"><span class="string">Set-Cookie</span><span>:</span> <span class="string">cookie2=value2; Path=/</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Custom"</span> not <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Content-Type"</span> <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Header1"</span> <span class="predicate-type">equals</span> <span class="string">"value1"</span></span><span class="line"><span class="query-type">header</span> <span class="string">"ETag"</span> <span class="predicate-type">equals</span> <span class="string">""33a64df551425fcc55e4d42a148795d9f25f89d4""</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Set-Cookie"</span> <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Set-Cookie"</span> <span class="predicate-type">equals</span> <span class="number">3</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Set-Cookie"</span> <span class="predicate-type">includes</span> <span class="string">"cookie1=value1; Path=/"</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Set-Cookie"</span> not <span class="predicate-type">includes</span> <span class="string">"cookie4=value4; Path=/"</span></span></div></div></div>
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/assert-header</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line"><span class="string">Content-Type</span><span>:</span> <span class="string">text/html; charset=utf-8</span></span><span class="line"><span class="string">Set-Cookie</span><span>:</span> <span class="string">cookie1=value1; Path=/</span></span><span class="line"><span class="string">Set-Cookie</span><span>:</span> <span class="string">cookie2=value2; Path=/</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Custom"</span> not <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Content-Type"</span> <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Header1"</span> <span class="predicate-type">equals</span> <span class="string">"value1"</span></span><span class="line"><span class="query-type">header</span> <span class="string">"ETag"</span> <span class="predicate-type">equals</span> <span class="string">""33a64df551425fcc55e4d42a148795d9f25f89d4""</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Set-Cookie"</span> <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Set-Cookie"</span> <span class="predicate-type">countEquals</span> <span class="number">3</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Set-Cookie"</span> <span class="predicate-type">includes</span> <span class="string">"cookie1=value1; Path=/"</span></span><span class="line"><span class="query-type">header</span> <span class="string">"Set-Cookie"</span> not <span class="predicate-type">includes</span> <span class="string">"cookie4=value4; Path=/"</span></span></div></div></div>

File diff suppressed because one or more lines are too long

View File

@ -2,9 +2,11 @@ GET http://localhost:8000/assert-json
HTTP/1.0 200
[Asserts]
jsonpath "$.count" equals 5
jsonpath "$.count" == 5
jsonpath "$.count" equals 5.0
jsonpath "$.count" greaterThan 1
jsonpath "$.count" greaterThan 1.0
jsonpath "$.count" >= 1.0
jsonpath "$.success" equals false
jsonpath "$.success" not equals null
jsonpath "$.success" exists
@ -22,6 +24,8 @@ jsonpath "$.errors[0]['id']" equals "error1"
jsonpath "$.errors[*].id" includes "error1"
jsonpath "$.duration" equals 1.5
jsonpath "$.duration" lessThanOrEquals 2.0
jsonpath "$.duration" <= 2.0
jsonpath "$.duration" lessThan 2
jsonpath "$.duration" lessThan 2
jsonpath "$.duration" isFloat
jsonpath "$.duration" not isInteger

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5.0}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1.0}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"equal","value":false}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"not":true,"type":"equal","value":null}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"isBoolean"}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"count","value":2}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"count","value":0}},{"query":{"type":"jsonpath","expr":"$.toto"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.errors[0]"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.errors[0]"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.errors[0].id"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[0]['id']"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[*].id"},"predicate":{"type":"include","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"equal","value":1.5}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less-or-equal","value":2.0}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"greater","value":2}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"isFloat"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"not":true,"type":"isInteger"}},{"query":{"type":"jsonpath","expr":"$.nullable"},"predicate":{"type":"equal","value":null}}],"body":{"type":"json","value":{"count":5,"success":false,"errors":[{"id":"error1"},{"id":"error2"}],"warnings":[],"duration":1.5,"tags":["test"],"nullable":null}}}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/index"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"index","query":{"type":"body"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors[{{index}}].id"},"predicate":{"type":"equal","value":"error2"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"type":"include","value":"test"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"not":true,"type":"include","value":"prod"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"not":true,"type":"include","value":null}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/list"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$"},"predicate":{"type":"count","value":2}},{"query":{"type":"jsonpath","expr":"$.[0].name"},"predicate":{"type":"equal","value":"Bob"}},{"query":{"type":"jsonpath","expr":"$[0].name"},"predicate":{"type":"equal","value":"Bob"}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5.0}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1.0}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater-or-equal","value":1.0}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"equal","value":false}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"not":true,"type":"equal","value":null}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"isBoolean"}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"count","value":2}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"count","value":0}},{"query":{"type":"jsonpath","expr":"$.toto"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.errors[0]"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.errors[0]"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.errors[0].id"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[0]['id']"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[*].id"},"predicate":{"type":"include","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"equal","value":1.5}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less-or-equal","value":2.0}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less-or-equal","value":2.0}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"greater","value":2}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"greater","value":2}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"isFloat"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"not":true,"type":"isInteger"}},{"query":{"type":"jsonpath","expr":"$.nullable"},"predicate":{"type":"equal","value":null}}],"body":{"type":"json","value":{"count":5,"success":false,"errors":[{"id":"error1"},{"id":"error2"}],"warnings":[],"duration":1.5,"tags":["test"],"nullable":null}}}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/index"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"index","query":{"type":"body"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors[{{index}}].id"},"predicate":{"type":"equal","value":"error2"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"type":"include","value":"test"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"not":true,"type":"include","value":"prod"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"not":true,"type":"include","value":null}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/list"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$"},"predicate":{"type":"count","value":2}},{"query":{"type":"jsonpath","expr":"$.[0].name"},"predicate":{"type":"equal","value":"Bob"}},{"query":{"type":"jsonpath","expr":"$[0].name"},"predicate":{"type":"equal","value":"Bob"}}]}}]}

View File

@ -1 +1 @@
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/bytes</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line"><span class="string">Content-Type</span><span>:</span> <span class="string">application/octet-stream</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">equals</span> <span class="hex">hex,ff;</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">equals</span> <span class="number">1</span></span><span class="line"><span class="query-type">sha256</span> <span class="predicate-type">equals</span> <span class="hex">hex,a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89;</span></span></div></div></div>
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/bytes</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line"><span class="string">Content-Type</span><span>:</span> <span class="string">application/octet-stream</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">equals</span> <span class="hex">hex,ff;</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">countEquals</span> <span class="number">1</span></span><span class="line"><span class="query-type">sha256</span> <span class="predicate-type">equals</span> <span class="hex">hex,a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89;</span></span></div></div></div>

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/predicate/error/type</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.status"</span> <span class="predicate-type">equals</span> <span class="string">"true"</span></span><span class="line"><span class="comment">#jsonpath "$.count" equals "0"</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.count"</span> <span class="predicate-type">equals</span> <span class="number">0</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">equals</span> <span class="number">0</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.empty"</span> <span class="predicate-type">equals</span> <span class="number">0</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.number"</span> <span class="predicate-type">equals</span> <span class="number">1.1</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">startsWith</span> <span class="string">"hi"</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">contains</span> <span class="string">"hi"</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">matches</span> <span class="string">"hi"</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">equals</span> <span class="number">1</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.toto"</span> <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> not <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.list"</span> <span class="predicate-type">equals</span> <span class="number">2</span></span></div></div></div>
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/predicate/error/type</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.status"</span> <span class="predicate-type">equals</span> <span class="string">"true"</span></span><span class="line"><span class="comment">#jsonpath "$.count" equals "0"</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.count"</span> <span class="predicate-type">equals</span> <span class="number">0</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">equals</span> <span class="number">0</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.empty"</span> <span class="predicate-type">equals</span> <span class="number">0</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.number"</span> <span class="predicate-type">equals</span> <span class="number">1.1</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">startsWith</span> <span class="string">"hi"</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">contains</span> <span class="string">"hi"</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">matches</span> <span class="string">"hi"</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> <span class="predicate-type">countEquals</span> <span class="number">1</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.toto"</span> <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.message"</span> not <span class="predicate-type">exists</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.list"</span> <span class="predicate-type">countEquals</span> <span class="number">2</span></span></div></div></div>

View File

@ -1 +1 @@
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/error-query-invalid-json</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.errors"</span> <span class="predicate-type">equals</span> <span class="number">2</span></span></div></div><span class="line"></span></div>
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/error-query-invalid-json</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.errors"</span> <span class="predicate-type">countEquals</span> <span class="number">2</span></span></div></div><span class="line"></span></div>

View File

@ -1 +1 @@
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/error-query-invalid-utf8</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.errors"</span> <span class="predicate-type">equals</span> <span class="number">2</span></span></div></div><span class="line"></span></div>
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/error-query-invalid-utf8</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.errors"</span> <span class="predicate-type">countEquals</span> <span class="number">2</span></span></div></div><span class="line"></span></div>

View File

@ -17,7 +17,6 @@
*/
use std::collections::HashMap;
use hex;
use regex::Regex;
use hurl_core::ast::*;
@ -841,6 +840,7 @@ mod tests {
value: PredicateFuncValue::EqualInt {
space0: whitespace,
value: 10,
operator: false,
},
source_info: SourceInfo::init(1, 11, 1, 12),
},
@ -876,6 +876,7 @@ mod tests {
value: PredicateFuncValue::EqualInt {
space0: whitespace,
value: 10,
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -901,6 +902,7 @@ mod tests {
value: PredicateFuncValue::EqualInt {
space0: whitespace,
value: 10,
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -927,6 +929,7 @@ mod tests {
value: PredicateFuncValue::EqualInt {
space0: whitespace.clone(),
value: 10,
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -944,6 +947,7 @@ mod tests {
value: PredicateFuncValue::EqualBool {
space0: whitespace.clone(),
value: true,
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -965,6 +969,7 @@ mod tests {
decimal: 200_000_000_000_000_000,
decimal_digits: 0,
},
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -1013,6 +1018,7 @@ mod tests {
value: PredicateFuncValue::EqualInt {
space0: whitespace.clone(),
value: 1,
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -1030,6 +1036,7 @@ mod tests {
value: PredicateFuncValue::EqualBool {
space0: whitespace.clone(),
value: false,
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -1051,6 +1058,7 @@ mod tests {
decimal: 1,
decimal_digits: 1,
},
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -1069,6 +1077,7 @@ mod tests {
value: PredicateFuncValue::EqualInt {
space0: whitespace,
value: 1,
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -1114,6 +1123,7 @@ mod tests {
value: PredicateFuncValue::EqualString {
space0: whitespace.clone(),
value: template.clone(),
operator: false,
},
source_info: SourceInfo::init(1, 1, 1, 21),
},
@ -1139,6 +1149,7 @@ mod tests {
value: PredicateFuncValue::EqualString {
space0: whitespace,
value: template,
operator: false,
},
source_info: SourceInfo::init(0, 0, 0, 0),
},
@ -1422,6 +1433,7 @@ mod tests {
source_info: SourceInfo::init(0, 0, 0, 0),
value: PredicateFuncValue::EqualNull {
space0: whitespace(),
operator: false,
},
},
};
@ -1471,6 +1483,7 @@ mod tests {
source_info: SourceInfo::init(0, 0, 0, 0),
value: PredicateFuncValue::EqualNull {
space0: whitespace(),
operator: false,
},
},
};
@ -1493,6 +1506,7 @@ mod tests {
source_info: SourceInfo::init(0, 0, 0, 0),
value: PredicateFuncValue::EqualNull {
space0: whitespace(),
operator: false,
},
},
};

View File

@ -400,31 +400,119 @@ pub struct PredicateFunc {
#[derive(Clone, Debug, PartialEq, Eq)]
#[allow(clippy::large_enum_variant)]
pub enum PredicateFuncValue {
EqualString { space0: Whitespace, value: Template },
EqualInt { space0: Whitespace, value: i64 },
EqualFloat { space0: Whitespace, value: Float },
EqualBool { space0: Whitespace, value: bool },
EqualNull { space0: Whitespace },
EqualHex { space0: Whitespace, value: Hex },
EqualExpression { space0: Whitespace, value: Expr },
GreaterThanInt { space0: Whitespace, value: i64 },
GreaterThanFloat { space0: Whitespace, value: Float },
GreaterThanOrEqualInt { space0: Whitespace, value: i64 },
GreaterThanOrEqualFloat { space0: Whitespace, value: Float },
LessThanInt { space0: Whitespace, value: i64 },
LessThanFloat { space0: Whitespace, value: Float },
LessThanOrEqualInt { space0: Whitespace, value: i64 },
LessThanOrEqualFloat { space0: Whitespace, value: Float },
CountEqual { space0: Whitespace, value: u64 },
StartWith { space0: Whitespace, value: Template },
Contain { space0: Whitespace, value: Template },
IncludeString { space0: Whitespace, value: Template },
IncludeInt { space0: Whitespace, value: i64 },
IncludeFloat { space0: Whitespace, value: Float },
IncludeBool { space0: Whitespace, value: bool },
IncludeNull { space0: Whitespace },
IncludeExpression { space0: Whitespace, value: Expr },
Match { space0: Whitespace, value: Template },
EqualString {
space0: Whitespace,
value: Template,
operator: bool,
},
EqualInt {
space0: Whitespace,
value: i64,
operator: bool,
},
EqualFloat {
space0: Whitespace,
value: Float,
operator: bool,
},
EqualBool {
space0: Whitespace,
value: bool,
operator: bool,
},
EqualNull {
space0: Whitespace,
operator: bool,
},
EqualHex {
space0: Whitespace,
value: Hex,
operator: bool,
},
EqualExpression {
space0: Whitespace,
value: Expr,
operator: bool,
},
GreaterThanInt {
space0: Whitespace,
value: i64,
operator: bool,
},
GreaterThanFloat {
space0: Whitespace,
value: Float,
operator: bool,
},
GreaterThanOrEqualInt {
space0: Whitespace,
value: i64,
operator: bool,
},
GreaterThanOrEqualFloat {
space0: Whitespace,
value: Float,
operator: bool,
},
LessThanInt {
space0: Whitespace,
value: i64,
operator: bool,
},
LessThanFloat {
space0: Whitespace,
value: Float,
operator: bool,
},
LessThanOrEqualInt {
space0: Whitespace,
value: i64,
operator: bool,
},
LessThanOrEqualFloat {
space0: Whitespace,
value: Float,
operator: bool,
},
CountEqual {
space0: Whitespace,
value: u64,
},
StartWith {
space0: Whitespace,
value: Template,
},
Contain {
space0: Whitespace,
value: Template,
},
IncludeString {
space0: Whitespace,
value: Template,
},
IncludeInt {
space0: Whitespace,
value: i64,
},
IncludeFloat {
space0: Whitespace,
value: Float,
},
IncludeBool {
space0: Whitespace,
value: bool,
},
IncludeNull {
space0: Whitespace,
},
IncludeExpression {
space0: Whitespace,
value: Expr,
},
Match {
space0: Whitespace,
value: Template,
},
IsInteger {},
IsFloat {},
IsBoolean {},

View File

@ -141,6 +141,74 @@ impl fmt::Display for Hex {
}
}
impl PredicateFuncValue {
pub fn name(&self) -> String {
match self {
PredicateFuncValue::EqualString { operator, .. }
| PredicateFuncValue::EqualInt { operator, .. }
| PredicateFuncValue::EqualFloat { operator, .. }
| PredicateFuncValue::EqualBool { operator, .. }
| PredicateFuncValue::EqualNull { operator, .. }
| PredicateFuncValue::EqualHex { operator, .. }
| PredicateFuncValue::EqualExpression { operator, .. } => {
if *operator {
"==".to_string()
} else {
"equals".to_string()
}
}
PredicateFuncValue::GreaterThanInt { operator, .. }
| PredicateFuncValue::GreaterThanFloat { operator, .. } => {
if *operator {
">".to_string()
} else {
"greaterThan".to_string()
}
}
PredicateFuncValue::GreaterThanOrEqualInt { operator, .. }
| PredicateFuncValue::GreaterThanOrEqualFloat { operator, .. } => {
if *operator {
">=".to_string()
} else {
"greaterThanOrEquals".to_string()
}
}
PredicateFuncValue::LessThanInt { operator, .. }
| PredicateFuncValue::LessThanFloat { operator, .. } => {
if *operator {
"<".to_string()
} else {
"lessThan".to_string()
}
}
PredicateFuncValue::LessThanOrEqualInt { operator, .. }
| PredicateFuncValue::LessThanOrEqualFloat { operator, .. } => {
if *operator {
"<=".to_string()
} else {
"lessThanOrEquals".to_string()
}
}
PredicateFuncValue::CountEqual { .. } => "countEquals".to_string(),
PredicateFuncValue::StartWith { .. } => "startsWith".to_string(),
PredicateFuncValue::Contain { .. } => "contains".to_string(),
PredicateFuncValue::IncludeString { .. }
| PredicateFuncValue::IncludeInt { .. }
| PredicateFuncValue::IncludeFloat { .. }
| PredicateFuncValue::IncludeBool { .. }
| PredicateFuncValue::IncludeNull { .. }
| PredicateFuncValue::IncludeExpression { .. } => "includes".to_string(),
PredicateFuncValue::Match { .. } => "matches".to_string(),
PredicateFuncValue::IsInteger { .. } => "isInteger".to_string(),
PredicateFuncValue::IsFloat { .. } => "isFloat".to_string(),
PredicateFuncValue::IsBoolean { .. } => "isBoolean".to_string(),
PredicateFuncValue::IsString { .. } => "isString".to_string(),
PredicateFuncValue::IsCollection { .. } => "isCollection".to_string(),
PredicateFuncValue::Exist { .. } => "exists".to_string(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -445,181 +445,255 @@ impl Htmlable for PredicateFuncValue {
fn to_html(&self) -> String {
let mut buffer = String::from("");
match self {
PredicateFuncValue::CountEqual { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">equals</span>");
PredicateFuncValue::CountEqual { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(format!("<span class=\"number\">{}</span>", value).as_str());
}
PredicateFuncValue::EqualString { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">equals</span>");
PredicateFuncValue::EqualString { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"string\">\"{}\"</span>", value.to_html()).as_str(),
);
}
PredicateFuncValue::EqualInt { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">equals</span>");
PredicateFuncValue::EqualInt { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(format!("<span class=\"number\">{}</span>", value).as_str());
}
PredicateFuncValue::EqualFloat { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">equals</span>");
PredicateFuncValue::EqualFloat { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::EqualHex { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">equals</span>");
PredicateFuncValue::EqualHex { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer
.push_str(format!("<span class=\"hex\">{}</span>", value.to_string()).as_str());
}
PredicateFuncValue::GreaterThanInt { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">greaterThan</span>");
PredicateFuncValue::GreaterThanInt { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::GreaterThanFloat { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">greaterThan</span>");
PredicateFuncValue::GreaterThanFloat { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::GreaterThanOrEqualInt { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">greaterThanOrEquals</span>");
PredicateFuncValue::GreaterThanOrEqualInt {
space0,
value,
operator,
} => {
buffer.push_str(
format!(
"<span class=\"predicate-type\">{}</span>",
if *operator {
">="
} else {
"greaterThanOrEquals"
}
)
.as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::GreaterThanOrEqualFloat { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">greaterThanOrEquals</span>");
PredicateFuncValue::GreaterThanOrEqualFloat { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::LessThanInt { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">lessThan</span>");
PredicateFuncValue::LessThanInt { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::LessThanFloat { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">lessThan</span>");
PredicateFuncValue::LessThanFloat { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::LessThanOrEqualInt { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">lessThanOrEquals</span>");
PredicateFuncValue::LessThanOrEqualInt { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::LessThanOrEqualFloat { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">lessThanOrEquals</span>");
PredicateFuncValue::LessThanOrEqualFloat { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::EqualExpression { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">equals</span>");
PredicateFuncValue::EqualExpression { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(value.to_html().as_str());
}
PredicateFuncValue::StartWith { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">startsWith</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"string\">\"{}\"</span>", value.to_html()).as_str(),
);
}
PredicateFuncValue::Contain { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">contains</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"string\">\"{}\"</span>", value.to_html()).as_str(),
);
}
PredicateFuncValue::IncludeString { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">includes</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"string\">\"{}\"</span>", value.to_html()).as_str(),
);
}
PredicateFuncValue::IncludeInt { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">includes</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(format!("<span class=\"number\">{}</span>", value).as_str());
}
PredicateFuncValue::IncludeNull { space0 } => {
buffer.push_str("<span class=\"predicate-type\">includes</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str("<span class=\"null\">null</span>");
}
PredicateFuncValue::IncludeBool { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">includes</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(format!("<span class=\"boolean\">{}</span>", value).as_str());
}
PredicateFuncValue::IncludeFloat { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">includes</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"number\">{}</span>", value.to_string()).as_str(),
);
}
PredicateFuncValue::IncludeExpression { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">includes</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push('"');
buffer.push_str(value.to_html().as_str());
buffer.push('"');
}
PredicateFuncValue::Match { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">matches</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(
format!("<span class=\"string\">\"{}\"</span>", value.to_html()).as_str(),
);
}
PredicateFuncValue::EqualNull { space0 } => {
buffer.push_str("<span class=\"predicate-type\">equals</span>");
PredicateFuncValue::EqualNull { space0, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str("<span class=\"null\">null</span>");
}
PredicateFuncValue::EqualBool { space0, value } => {
buffer.push_str("<span class=\"predicate-type\">equals</span>");
PredicateFuncValue::EqualBool { space0, value, .. } => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
buffer.push_str(space0.to_html().as_str());
buffer.push_str(format!("<span class=\"boolean\">{}</span>", value).as_str());
}
PredicateFuncValue::IsInteger {} => {
buffer.push_str("<span class=\"predicate-type\">isInteger</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
}
PredicateFuncValue::IsFloat {} => {
buffer.push_str("<span class=\"predicate-type\">isFloat</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
}
PredicateFuncValue::IsBoolean {} => {
buffer.push_str("<span class=\"predicate-type\">isBoolean</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
}
PredicateFuncValue::IsString {} => {
buffer.push_str("<span class=\"predicate-type\">isString</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
}
PredicateFuncValue::IsCollection {} => {
buffer.push_str("<span class=\"predicate-type\">isCollection</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
}
PredicateFuncValue::Exist {} => {
buffer.push_str("<span class=\"predicate-type\">exists</span>");
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
}
}
buffer

View File

@ -93,23 +93,48 @@ fn predicate_func_value(reader: &mut Reader) -> ParseResult<'static, PredicateFu
}
fn equal_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValue> {
try_literal("equals", reader)?;
let space0 = one_or_more_spaces(reader)?;
let operator = try_literals("equals", "==", reader)? == "==";
let space0 = if operator {
zero_or_more_spaces(reader)?
} else {
one_or_more_spaces(reader)?
};
let start = reader.state.clone();
// TODO To be refactored - use idiomatic choice with correct recoverable behaviour
match predicate_value(reader) {
Ok(PredicateValue::Null {}) => Ok(PredicateFuncValue::EqualNull { space0 }),
Ok(PredicateValue::Bool { value }) => Ok(PredicateFuncValue::EqualBool { space0, value }),
Ok(PredicateValue::Int { value }) => Ok(PredicateFuncValue::EqualInt { space0, value }),
Ok(PredicateValue::Float { value }) => Ok(PredicateFuncValue::EqualFloat { space0, value }),
Ok(PredicateValue::Hex { value }) => Ok(PredicateFuncValue::EqualHex { space0, value }),
Ok(PredicateValue::Expression { value }) => {
Ok(PredicateFuncValue::EqualExpression { space0, value })
}
Ok(PredicateValue::Template { value }) => {
Ok(PredicateFuncValue::EqualString { space0, value })
}
Ok(PredicateValue::Null {}) => Ok(PredicateFuncValue::EqualNull { space0, operator }),
Ok(PredicateValue::Bool { value }) => Ok(PredicateFuncValue::EqualBool {
space0,
value,
operator,
}),
Ok(PredicateValue::Int { value }) => Ok(PredicateFuncValue::EqualInt {
space0,
value,
operator,
}),
Ok(PredicateValue::Float { value }) => Ok(PredicateFuncValue::EqualFloat {
space0,
value,
operator,
}),
Ok(PredicateValue::Hex { value }) => Ok(PredicateFuncValue::EqualHex {
space0,
value,
operator,
}),
Ok(PredicateValue::Expression { value }) => Ok(PredicateFuncValue::EqualExpression {
space0,
value,
operator,
}),
Ok(PredicateValue::Template { value }) => Ok(PredicateFuncValue::EqualString {
space0,
value,
operator,
}),
Err(e) => match e.inner {
ParseError::EscapeChar {} | ParseError::OddNumberOfHexDigits {} => Err(e),
_ => Err(Error {
@ -122,17 +147,24 @@ fn equal_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncVal
}
fn greater_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValue> {
try_literal("greaterThan", reader)?;
let space0 = one_or_more_spaces(reader)?;
let operator = try_literals("greaterThan", ">=", reader)? == ">=";
let space0 = if operator {
zero_or_more_spaces(reader)?
} else {
one_or_more_spaces(reader)?
};
let start = reader.state.clone();
match predicate_value(reader) {
Ok(PredicateValue::Int { value }) => {
Ok(PredicateFuncValue::GreaterThanInt { space0, value })
}
Ok(PredicateValue::Float { value }) => {
Ok(PredicateFuncValue::GreaterThanFloat { space0, value })
}
Ok(PredicateValue::Int { value }) => Ok(PredicateFuncValue::GreaterThanInt {
space0,
value,
operator,
}),
Ok(PredicateValue::Float { value }) => Ok(PredicateFuncValue::GreaterThanFloat {
space0,
value,
operator,
}),
Ok(_) => Err(Error {
pos: start.pos,
recoverable: false,
@ -148,18 +180,26 @@ fn greater_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncV
},
}
}
fn greater_or_equal_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValue> {
try_literal("greaterThanOrEquals", reader)?;
let space0 = one_or_more_spaces(reader)?;
let start = reader.state.clone();
fn greater_or_equal_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValue> {
let operator = try_literals("greaterThanOrEquals", ">=", reader)? == ">=";
let space0 = if operator {
zero_or_more_spaces(reader)?
} else {
one_or_more_spaces(reader)?
};
let start = reader.state.clone();
match predicate_value(reader) {
Ok(PredicateValue::Int { value }) => {
Ok(PredicateFuncValue::GreaterThanOrEqualInt { space0, value })
}
Ok(PredicateValue::Float { value }) => {
Ok(PredicateFuncValue::GreaterThanOrEqualFloat { space0, value })
}
Ok(PredicateValue::Int { value }) => Ok(PredicateFuncValue::GreaterThanOrEqualInt {
space0,
value,
operator,
}),
Ok(PredicateValue::Float { value }) => Ok(PredicateFuncValue::GreaterThanOrEqualFloat {
space0,
value,
operator,
}),
Ok(_) => Err(Error {
pos: start.pos,
recoverable: false,
@ -177,15 +217,24 @@ fn greater_or_equal_predicate(reader: &mut Reader) -> ParseResult<'static, Predi
}
fn less_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValue> {
try_literal("lessThan", reader)?;
let space0 = one_or_more_spaces(reader)?;
let operator = try_literals("lessThan", "<", reader)? == "<";
let space0 = if operator {
zero_or_more_spaces(reader)?
} else {
one_or_more_spaces(reader)?
};
let start = reader.state.clone();
match predicate_value(reader) {
Ok(PredicateValue::Int { value }) => Ok(PredicateFuncValue::LessThanInt { space0, value }),
Ok(PredicateValue::Float { value }) => {
Ok(PredicateFuncValue::LessThanFloat { space0, value })
}
Ok(PredicateValue::Int { value }) => Ok(PredicateFuncValue::LessThanInt {
space0,
value,
operator,
}),
Ok(PredicateValue::Float { value }) => Ok(PredicateFuncValue::LessThanFloat {
space0,
value,
operator,
}),
Ok(_) => Err(Error {
pos: start.pos,
recoverable: false,
@ -201,18 +250,26 @@ fn less_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValu
},
}
}
fn less_or_equal_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValue> {
try_literal("lessThanOrEquals", reader)?;
let space0 = one_or_more_spaces(reader)?;
let start = reader.state.clone();
fn less_or_equal_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValue> {
let operator = try_literals("lessThanOrEquals", "<=", reader)? == "<=";
let space0 = if operator {
zero_or_more_spaces(reader)?
} else {
one_or_more_spaces(reader)?
};
let start = reader.state.clone();
match predicate_value(reader) {
Ok(PredicateValue::Int { value }) => {
Ok(PredicateFuncValue::LessThanOrEqualInt { space0, value })
}
Ok(PredicateValue::Float { value }) => {
Ok(PredicateFuncValue::LessThanOrEqualFloat { space0, value })
}
Ok(PredicateValue::Int { value }) => Ok(PredicateFuncValue::LessThanOrEqualInt {
space0,
value,
operator,
}),
Ok(PredicateValue::Float { value }) => Ok(PredicateFuncValue::LessThanOrEqualFloat {
space0,
value,
operator,
}),
Ok(_) => Err(Error {
pos: start.pos,
recoverable: false,
@ -239,7 +296,7 @@ fn count_equal_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateF
pos: save.pos,
recoverable: false,
inner: ParseError::PredicateValue {},
})
});
}
Ok(value) => value,
};
@ -401,6 +458,7 @@ mod tests {
source_info: SourceInfo::init(1, 11, 1, 12),
},
value: true,
operator: false
},
},
}
@ -415,7 +473,7 @@ mod tests {
error.pos,
Pos {
line: 1,
column: 13
column: 13,
}
);
assert_eq!(error.recoverable, false);
@ -442,6 +500,8 @@ mod tests {
value: String::from(" "),
source_info: SourceInfo::init(1, 7, 1, 9),
},
operator: false
}
);
@ -452,12 +512,13 @@ mod tests {
value: Float {
int: 1,
decimal: 100_000_000_000_000_000,
decimal_digits: 1
decimal_digits: 1,
},
space0: Whitespace {
value: String::from(" "),
source_info: SourceInfo::init(1, 7, 1, 8),
},
operator: false
}
);
@ -470,7 +531,21 @@ mod tests {
value: String::from(" "),
source_info: SourceInfo::init(1, 7, 1, 8),
},
}
operator: false
},
);
let mut reader = Reader::init("== 2");
assert_eq!(
equal_predicate(&mut reader).unwrap(),
PredicateFuncValue::EqualInt {
value: 2,
space0: Whitespace {
value: String::from(" "),
source_info: SourceInfo::init(1, 3, 1, 4),
},
operator: true
},
);
let mut reader = Reader::init("equals \"Bob\"");
@ -489,6 +564,7 @@ mod tests {
value: String::from(" "),
source_info: SourceInfo::init(1, 7, 1, 8),
},
operator: false
}
);
}
@ -517,6 +593,7 @@ mod tests {
value: String::from(" "),
source_info: SourceInfo::init(1, 7, 1, 8),
},
operator: false
}
);
}
@ -541,7 +618,7 @@ mod tests {
error.pos,
Pos {
line: 1,
column: 13
column: 13,
}
);
assert_eq!(error.recoverable, false);
@ -556,7 +633,7 @@ mod tests {
error.pos,
Pos {
line: 1,
column: 12
column: 12,
}
);
assert_eq!(error.recoverable, false);
@ -589,7 +666,7 @@ mod tests {
value: Float {
int: 1,
decimal: 100_000_000_000_000_000,
decimal_digits: 1
decimal_digits: 1,
}
}
);

View File

@ -210,6 +210,30 @@ pub fn try_literal(s: &str, reader: &mut Reader) -> ParseResult<'static, ()> {
}
}
// return the literal string
pub fn try_literals(s1: &str, s2: &str, reader: &mut Reader) -> ParseResult<'static, String> {
let start = reader.state.clone();
match literal(s1, reader) {
Ok(_) => Ok(s1.to_string()),
Err(_) => {
reader.state = start.clone();
match literal(s2, reader) {
Ok(_) => Ok(s2.to_string()),
Err(_) => {
reader.state = start.clone();
return Err(Error {
pos: start.pos,
recoverable: true,
inner: ParseError::Expecting {
value: format!("<{}> or <{}>", s1, s2),
},
});
}
}
}
}
}
pub fn newline(reader: &mut Reader) -> ParseResult<'static, Whitespace> {
let start = reader.state.clone();
match try_literal("\r\n", reader) {

View File

@ -445,6 +445,7 @@ mod tests {
}],
source_info: SourceInfo::init(2, 26, 2, 45),
},
operator: false
},
},
},
@ -782,6 +783,7 @@ mod tests {
source_info: SourceInfo::init(1, 27, 1, 28),
},
value: 5,
operator: false
},
},
}

View File

@ -691,6 +691,7 @@ pub mod tests {
value: PredicateFuncValue::EqualInt {
space0: whitespace(),
value,
operator: false,
},
},
}

View File

@ -528,149 +528,149 @@ impl Tokenizable for PredicateFuncValue {
fn tokenize(&self) -> Vec<Token> {
let mut tokens: Vec<Token> = vec![];
match self {
PredicateFuncValue::EqualNull { space0 } => {
tokens.push(Token::PredicateType(String::from("equals")));
PredicateFuncValue::EqualNull { space0, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Keyword("null".to_string()));
}
PredicateFuncValue::EqualBool { space0, value } => {
tokens.push(Token::PredicateType(String::from("equals")));
PredicateFuncValue::EqualBool { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Boolean(value.to_string()));
}
PredicateFuncValue::EqualString { space0, value } => {
tokens.push(Token::PredicateType(String::from("equals")));
PredicateFuncValue::EqualString { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
add_tokens(&mut tokens, value.tokenize());
}
PredicateFuncValue::EqualInt { space0, value } => {
tokens.push(Token::PredicateType(String::from("equals")));
PredicateFuncValue::EqualInt { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::EqualFloat { space0, value } => {
tokens.push(Token::PredicateType(String::from("equals")));
PredicateFuncValue::EqualFloat { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::EqualHex { space0, value } => {
tokens.push(Token::PredicateType(String::from("equals")));
PredicateFuncValue::EqualHex { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::String(value.to_string()));
}
PredicateFuncValue::EqualExpression { space0, value } => {
tokens.push(Token::PredicateType(String::from("equals")));
PredicateFuncValue::EqualExpression { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.append(&mut value.tokenize());
}
PredicateFuncValue::GreaterThanInt { space0, value } => {
tokens.push(Token::PredicateType(String::from("greaterThan")));
PredicateFuncValue::GreaterThanInt { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::GreaterThanFloat { space0, value } => {
tokens.push(Token::PredicateType(String::from("greaterThan")));
PredicateFuncValue::GreaterThanFloat { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::GreaterThanOrEqualInt { space0, value } => {
tokens.push(Token::PredicateType(String::from("greaterThanOrEquals")));
PredicateFuncValue::GreaterThanOrEqualInt { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::GreaterThanOrEqualFloat { space0, value } => {
tokens.push(Token::PredicateType(String::from("greaterThanOrEquals")));
PredicateFuncValue::GreaterThanOrEqualFloat { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::LessThanInt { space0, value } => {
tokens.push(Token::PredicateType(String::from("lessThan")));
PredicateFuncValue::LessThanInt { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::LessThanFloat { space0, value } => {
tokens.push(Token::PredicateType(String::from("lessThan")));
PredicateFuncValue::LessThanFloat { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::LessThanOrEqualInt { space0, value } => {
tokens.push(Token::PredicateType(String::from("lessThanOrEquals")));
PredicateFuncValue::LessThanOrEqualInt { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::LessThanOrEqualFloat { space0, value } => {
tokens.push(Token::PredicateType(String::from("lessThanOrEquals")));
PredicateFuncValue::LessThanOrEqualFloat { space0, value, .. } => {
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::CountEqual { space0, value } => {
tokens.push(Token::PredicateType(String::from("countEquals")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Boolean(value.to_string()));
}
PredicateFuncValue::StartWith { space0, value } => {
tokens.push(Token::PredicateType(String::from("startsWith")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
add_tokens(&mut tokens, value.tokenize());
}
PredicateFuncValue::Contain { space0, value } => {
tokens.push(Token::PredicateType(String::from("contains")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
add_tokens(&mut tokens, value.tokenize());
}
PredicateFuncValue::IncludeString { space0, value } => {
tokens.push(Token::PredicateType(String::from("includes")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
add_tokens(&mut tokens, value.tokenize());
}
PredicateFuncValue::IncludeInt { space0, value } => {
tokens.push(Token::PredicateType(String::from("includes")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::IncludeFloat { space0, value } => {
tokens.push(Token::PredicateType(String::from("includes")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Number(value.to_string()));
}
PredicateFuncValue::IncludeNull { space0 } => {
tokens.push(Token::PredicateType(String::from("includes")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Keyword("null".to_string()));
}
PredicateFuncValue::IncludeBool { space0, value } => {
tokens.push(Token::PredicateType(String::from("includes")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.push(Token::Boolean(value.to_string()));
}
PredicateFuncValue::IncludeExpression { space0, value } => {
tokens.push(Token::PredicateType(String::from("includes")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
tokens.append(&mut value.tokenize());
}
PredicateFuncValue::Match { space0, value } => {
tokens.push(Token::PredicateType(String::from("matches")));
tokens.push(Token::PredicateType(self.name()));
add_tokens(&mut tokens, space0.tokenize());
add_tokens(&mut tokens, value.tokenize());
}
PredicateFuncValue::IsInteger {} => {
tokens.push(Token::PredicateType(String::from("isInteger")));
tokens.push(Token::PredicateType(self.name()));
}
PredicateFuncValue::IsFloat {} => {
tokens.push(Token::PredicateType(String::from("isFloat")));
tokens.push(Token::PredicateType(self.name()));
}
PredicateFuncValue::IsBoolean {} => {
tokens.push(Token::PredicateType(String::from("isBoolean")));
tokens.push(Token::PredicateType(self.name()));
}
PredicateFuncValue::IsString {} => {
tokens.push(Token::PredicateType(String::from("isString")));
tokens.push(Token::PredicateType(self.name()));
}
PredicateFuncValue::IsCollection {} => {
tokens.push(Token::PredicateType(String::from("isCollection")));
tokens.push(Token::PredicateType(self.name()));
}
PredicateFuncValue::Exist {} => {
tokens.push(Token::PredicateType(String::from("exists")));
tokens.push(Token::PredicateType(self.name()));
}
}
tokens

View File

@ -389,76 +389,91 @@ impl Lintable<PredicateFuncValue> for PredicateFuncValue {
PredicateFuncValue::EqualString { value, .. } => PredicateFuncValue::EqualString {
space0: one_whitespace(),
value: value.clone().lint(),
operator: true,
},
PredicateFuncValue::EqualInt { value, .. } => PredicateFuncValue::EqualInt {
space0: one_whitespace(),
value: value.clone(),
operator: true,
},
PredicateFuncValue::EqualBool { value, .. } => PredicateFuncValue::EqualBool {
space0: one_whitespace(),
value: value.clone(),
operator: true,
},
PredicateFuncValue::EqualNull { .. } => PredicateFuncValue::EqualNull {
space0: one_whitespace(),
operator: true,
},
PredicateFuncValue::EqualFloat { value, .. } => PredicateFuncValue::EqualFloat {
space0: one_whitespace(),
value: value.clone(),
operator: true,
},
PredicateFuncValue::EqualHex { value, .. } => PredicateFuncValue::EqualHex {
space0: one_whitespace(),
value: value.lint(),
operator: true,
},
PredicateFuncValue::EqualExpression { value, .. } => {
PredicateFuncValue::EqualExpression {
space0: one_whitespace(),
value: value.clone(),
operator: true,
}
}
PredicateFuncValue::GreaterThanInt { value, .. } => {
PredicateFuncValue::GreaterThanInt {
space0: one_whitespace(),
value: value.clone(),
operator: true,
}
}
PredicateFuncValue::GreaterThanFloat { value, .. } => {
PredicateFuncValue::GreaterThanFloat {
space0: one_whitespace(),
value: value.clone(),
operator: true,
}
}
PredicateFuncValue::GreaterThanOrEqualInt { value, .. } => {
PredicateFuncValue::GreaterThanOrEqualInt {
space0: one_whitespace(),
value: value.clone(),
operator: true,
}
}
PredicateFuncValue::GreaterThanOrEqualFloat { value, .. } => {
PredicateFuncValue::GreaterThanOrEqualFloat {
space0: one_whitespace(),
value: value.clone(),
operator: true,
}
}
PredicateFuncValue::LessThanInt { value, .. } => PredicateFuncValue::GreaterThanInt {
space0: one_whitespace(),
value: value.clone(),
operator: true,
},
PredicateFuncValue::LessThanFloat { value, .. } => {
PredicateFuncValue::GreaterThanFloat {
space0: one_whitespace(),
value: value.clone(),
operator: true,
}
}
PredicateFuncValue::LessThanOrEqualInt { value, .. } => {
PredicateFuncValue::GreaterThanOrEqualInt {
space0: one_whitespace(),
value: value.clone(),
operator: true,
}
}
PredicateFuncValue::LessThanOrEqualFloat { value, .. } => {
PredicateFuncValue::GreaterThanOrEqualFloat {
space0: one_whitespace(),
value: value.clone(),
operator: true,
}
}
PredicateFuncValue::Contain { value, .. } => PredicateFuncValue::Contain {