Cutelee 6.1.0
typeaccessors.cpp
1/*
2 This file is part of the Cutelee template system.
3
4 Copyright (c) 2010 Stephen Kelly <steveire@gmail.com>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either version
9 2.1 of the Licence, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library. If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21#include "typeaccessor.h"
22
23#include "metaenumvariable_p.h"
24#include "safestring.h"
25
26#include <QtCore/QRegularExpression>
27#include <QtCore/QStringList>
28#include <QtCore/QVariant>
29
30namespace Cutelee
31{
32
33static QRegularExpression getIsTitleRE()
34{
35 QRegularExpression titleRe(QStringLiteral("\\b[a-z]"),
36 QRegularExpression::InvertedGreedinessOption);
37 return titleRe;
38}
39
40static QRegularExpression getTitleRE()
41{
42 QRegularExpression titleRe(QStringLiteral("\\b(.)"),
43 QRegularExpression::InvertedGreedinessOption);
44 return titleRe;
45}
46
47template <>
49TypeAccessor<Cutelee::SafeString &>::lookUp(const Cutelee::SafeString &object,
50 const QString &property)
51{
52 if (property == QStringLiteral("capitalize")) {
53 const QString s = object.get();
54 return QVariant(s.at(0).toUpper() + s.right(s.length() - 1));
55 }
56
57 static const QLatin1String falseString("False");
58 static const QLatin1String trueString("True");
59
60 if (property == QStringLiteral("isalnum")) {
61 const QString s = object.get();
62 auto it = s.constBegin();
63 while (it != s.constEnd()) {
64 if (!it->isLetterOrNumber())
65 return falseString;
66 ++it;
67 }
68 return trueString;
69 }
70 if (property == QStringLiteral("isalpha")) {
71 const QString s = object.get();
72 auto it = s.constBegin();
73 if (it == s.constEnd())
74 return falseString;
75 while (it != s.constEnd()) {
76 if (!it->isLetter())
77 return falseString;
78 ++it;
79 }
80 return trueString;
81 }
82 if (property == QStringLiteral("isdigit")) {
83 const QString s = object.get();
84 auto it = s.constBegin();
85 while (it != s.constEnd()) {
86 if (!it->isNumber())
87 return falseString;
88 ++it;
89 }
90 return trueString;
91 }
92 if (property == QStringLiteral("islower")) {
93 const QString s = object.get().toLower();
94 return (s == object.get()) ? trueString : falseString;
95 }
96 if (property == QStringLiteral("isspace")) {
97 const QString s = object.get().trimmed();
98 return (s.isEmpty()) ? trueString : falseString;
99 }
100 if (property == QStringLiteral("istitle")) {
101 const QString s = object.get();
102
103 static const auto titleRe = getIsTitleRE();
104 return (titleRe.match(s).hasMatch()) ? falseString : trueString;
105 }
106 if (property == QStringLiteral("isupper")) {
107 const QString s = object.get().toUpper();
108 return (s == object) ? trueString : falseString;
109 }
110 if (property == QStringLiteral("lower")) {
111 return object.get().toLower();
112 }
113 if (property == QStringLiteral("splitlines")) {
114 const auto strings = object.get().split(QLatin1Char('\n'));
115 QVariantList list;
116 auto it = strings.constBegin();
117 const auto end = strings.constEnd();
118 for (; it != end; ++it)
119 list << *it;
120 return list;
121 }
122 if (property == QStringLiteral("strip")) {
123 return object.get().trimmed();
124 }
125 if (property == QStringLiteral("swapcase")) {
126 const QString inputString = object.get();
127 QString s;
128 s.reserve(inputString.size());
129 auto it = inputString.constBegin();
130 while (it != inputString.constEnd()) {
131 if (it->isUpper())
132 s += it->toLower();
133 else if (it->isLower())
134 s += it->toUpper();
135 else
136 s += *it;
137 ++it;
138 }
139 return s;
140 }
141 if (property == QStringLiteral("title")) {
142 static const auto titleRe = getTitleRE();
143
144 const QString s = object.get();
145 QString output;
146 output.reserve(s.size());
147 auto pos = 0;
148 auto nextPos = 0;
149 int matchedLength;
150
151 auto it = titleRe.globalMatch(s);
152 while (it.hasNext()) {
153 auto match = it.next();
154 pos = match.capturedStart();
155 output += match.captured().toUpper();
156 matchedLength = match.capturedLength();
157 if (it.hasNext()) {
158 match = it.peekNext();
159 nextPos = match.capturedStart();
160 output += s.mid(pos + matchedLength, nextPos - pos - 1);
161 } else {
162 output += s.right(s.length() - (pos + matchedLength));
163 }
164 }
165
166 return output;
167 }
168 if (property == QStringLiteral("upper")) {
169 return object.get().toUpper();
170 }
171 return QVariant();
172}
173
174template <>
176TypeAccessor<MetaEnumVariable &>::lookUp(const MetaEnumVariable &object,
177 const QString &property)
178{
179 if (property == QStringLiteral("name"))
180 return QLatin1String(object.enumerator.name());
181 if (property == QStringLiteral("value"))
182 return object.value;
183 if (property == QStringLiteral("key"))
184 return QLatin1String(object.enumerator.valueToKey(object.value));
185 if (property == QStringLiteral("scope"))
186 return QLatin1String(object.enumerator.scope());
187 if (property == QStringLiteral("keyCount"))
188 return object.enumerator.keyCount();
189
190 auto ok = false;
191 const auto listIndex = property.toInt(&ok);
192 if (ok) {
193 if (listIndex >= object.enumerator.keyCount())
194 return QVariant();
195
196 const MetaEnumVariable mev(object.enumerator,
197 object.enumerator.value(listIndex));
198 return QVariant::fromValue(mev);
199 }
200
201 return QVariant();
202}
203}
A QString wrapper class for containing whether a string is safe or needs to be escaped.
Definition safestring.h:92
The Cutelee namespace holds all public Cutelee API.
Definition Mainpage.dox:8