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 
30 namespace Cutelee
31 {
32 
33 static QRegularExpression getIsTitleRE()
34 {
35  QRegularExpression titleRe(QStringLiteral("\\b[a-z]"),
36  QRegularExpression::InvertedGreedinessOption);
37  return titleRe;
38 }
39 
40 static QRegularExpression getTitleRE()
41 {
42  QRegularExpression titleRe(QStringLiteral("\\b(.)"),
43  QRegularExpression::InvertedGreedinessOption);
44  return titleRe;
45 }
46 
47 template <>
49 TypeAccessor<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 
174 template <>
175 QVariant
176 TypeAccessor<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