blob: e0272e2ecc7bfd5d703399ad36d4037766ea81e2 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "predicate.h"
#include "predicate_printer.h"
#include <vespa/document/util/stringutil.h>
#include <vespa/vespalib/data/slime/slime.h>
#include <vespa/vespalib/stllike/asciistream.h>
using vespalib::Slime;
using vespalib::slime::Inspector;
namespace document {
namespace {
void printEscapedString(vespalib::asciistream &out, const Inspector &in) {
out << "'" << StringUtil::escape(in.asString().make_string(), '\'') << "'";
}
} // namespace
vespalib::string
PredicatePrinter::str() const {
return _out->str();
}
PredicatePrinter::PredicatePrinter() : _out(new vespalib::asciistream()), _negated(false) {}
PredicatePrinter::~PredicatePrinter() { }
void PredicatePrinter::visitFeatureSet(const Inspector &in) {
printEscapedString(*_out, in[Predicate::KEY]);
if (_negated) {
*_out << " not";
}
*_out << " in [";
for (size_t i = 0; i < in[Predicate::SET].entries(); ++i) {
if (i) {
*_out << ",";
}
printEscapedString(*_out, in[Predicate::SET][i]);
}
*_out << "]";
}
void PredicatePrinter::visitFeatureRange(const Inspector &in) {
printEscapedString(*_out, in[Predicate::KEY]);
if (_negated) {
*_out << " not";
}
bool has_min = in[Predicate::RANGE_MIN].valid();
bool has_max = in[Predicate::RANGE_MAX].valid();
*_out << " in [";
if (has_min) *_out << in[Predicate::RANGE_MIN].asLong();
*_out << "..";
if (has_max) *_out << in[Predicate::RANGE_MAX].asLong();
*_out << "]";
}
void PredicatePrinter::visitNegation(const Inspector &in) {
bool n = _negated;
_negated = !_negated;
visitChildren(in);
_negated = n;
}
void PredicatePrinter::visitConjunction(const Inspector &in) {
if (_negated)
*_out << "not ";
_negated = false;
*_out << "(";
for (size_t i = 0; i < in[Predicate::CHILDREN].children(); ++i) {
if (i) {
*_out << " and ";
}
visit(in[Predicate::CHILDREN][i]);
}
*_out << ")";
}
void PredicatePrinter::visitDisjunction(const Inspector &in) {
if (_negated)
*_out << "not ";
_negated = false;
*_out << "(";
for (size_t i = 0; i < in[Predicate::CHILDREN].children(); ++i) {
if (i) {
*_out << " or ";
}
visit(in[Predicate::CHILDREN][i]);
}
*_out << ")";
}
void PredicatePrinter::visitTrue(const Inspector &) {
*_out << "true";
}
void PredicatePrinter::visitFalse(const Inspector &) {
*_out << "false";
}
vespalib::string PredicatePrinter::print(const Slime &slime) {
PredicatePrinter printer;
printer.visit(slime.get());
return printer.str();
}
} // namespace document
|