1 /*
2 * LibrePCB - Professional EDA for everyone!
3 * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4 * https://librepcb.org/
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef LIBREPCB_LIBRARY_COMPONENTSYMBOLVARIANTITEMSUFFIX_H
21 #define LIBREPCB_LIBRARY_COMPONENTSYMBOLVARIANTITEMSUFFIX_H
22
23 /*******************************************************************************
24 * Includes
25 ******************************************************************************/
26 #include <librepcb/common/fileio/sexpression.h>
27 #include <type_safe/constrained_type.hpp>
28
29 #include <QtCore>
30
31 /*******************************************************************************
32 * Namespace / Forward Declarations
33 ******************************************************************************/
34 namespace librepcb {
35 namespace library {
36
37 /*******************************************************************************
38 * Class ComponentSymbolVariantItemSuffix
39 ******************************************************************************/
40
41 struct ComponentSymbolVariantItemSuffixVerifier {
42 template <typename Value, typename Predicate>
43 static constexpr auto verify(Value&& val, const Predicate& p) ->
44 typename std::decay<Value>::type {
45 return p(val) ? std::forward<Value>(val)
46 : (throw RuntimeError(
47 __FILE__, __LINE__,
48 QString(QApplication::translate(
49 "ComponentSymbolVariantItemSuffix",
50 "Invalid component symbol suffix: '%1'"))
51 .arg(val)),
52 std::forward<Value>(val));
53 }
54 };
55
56 struct ComponentSymbolVariantItemSuffixConstraint {
operatorComponentSymbolVariantItemSuffixConstraint57 bool operator()(const QString& value) const noexcept {
58 return QRegularExpression("\\A[0-9a-zA-Z_]{0,16}\\z")
59 .match(value, 0, QRegularExpression::PartialPreferCompleteMatch)
60 .hasMatch();
61 }
62 };
63
64 /**
65 * ComponentSymbolVariantItemSuffix is a wrapper around QString which guarantees
66 * to contain a valid suffix used for
67 * librepcb::library::ComponentSymbolVariantItem
68 *
69 * Such a suffix is considered as valid if it:
70 * - contains only the characters [0-9a-zA-Z_-]
71 * - is not longer than 16 characters
72 *
73 * The constructor throws an exception if constructed from a QString which is
74 * not a valid suffix according these rules.
75 */
76 using ComponentSymbolVariantItemSuffix =
77 type_safe::constrained_type<QString,
78 ComponentSymbolVariantItemSuffixConstraint,
79 ComponentSymbolVariantItemSuffixVerifier>;
80
81 } // namespace library
82
83 inline bool operator==(const library::ComponentSymbolVariantItemSuffix& lhs,
84 const QString& rhs) noexcept {
85 return (*lhs) == rhs;
86 }
87 inline bool operator==(
88 const QString& lhs,
89 const library::ComponentSymbolVariantItemSuffix& rhs) noexcept {
90 return lhs == (*rhs);
91 }
92 inline bool operator!=(const library::ComponentSymbolVariantItemSuffix& lhs,
93 const QString& rhs) noexcept {
94 return (*lhs) != rhs;
95 }
96 inline bool operator!=(
97 const QString& lhs,
98 const library::ComponentSymbolVariantItemSuffix& rhs) noexcept {
99 return lhs != (*rhs);
100 }
101 inline QString operator%(const library::ComponentSymbolVariantItemSuffix& lhs,
102 const QString& rhs) noexcept {
103 return (*lhs) % rhs;
104 }
105 inline QString operator%(
106 const QString& lhs,
107 const library::ComponentSymbolVariantItemSuffix& rhs) noexcept {
108 return lhs % (*rhs);
109 }
110
111 template <>
serialize(const library::ComponentSymbolVariantItemSuffix & obj)112 inline SExpression serialize(
113 const library::ComponentSymbolVariantItemSuffix& obj) {
114 return SExpression::createString(*obj);
115 }
116
117 template <>
deserialize(const SExpression & sexpr,const Version & fileFormat)118 inline library::ComponentSymbolVariantItemSuffix deserialize(
119 const SExpression& sexpr, const Version& fileFormat) {
120 Q_UNUSED(fileFormat);
121 return library::ComponentSymbolVariantItemSuffix(
122 sexpr.getValue()); // can throw
123 }
124
125 inline QDataStream& operator<<(
126 QDataStream& stream, const library::ComponentSymbolVariantItemSuffix& obj) {
127 stream << *obj;
128 return stream;
129 }
130
131 inline QDebug operator<<(QDebug stream,
132 const library::ComponentSymbolVariantItemSuffix& obj) {
133 stream << QString("ComponentSymbolVariantItemSuffix('%1'')").arg(*obj);
134 return stream;
135 }
136
137 inline uint qHash(const library::ComponentSymbolVariantItemSuffix& key,
138 uint seed = 0) noexcept {
139 return ::qHash(*key, seed);
140 }
141
142 /*******************************************************************************
143 * End of File
144 ******************************************************************************/
145
146 } // namespace librepcb
147
148 #endif // LIBREPCB_LIBRARY_COMPONENTSYMBOLVARIANTITEMSUFFIX_H
149