File indexing completed on 2024-05-12 04:42:45
0001 /* 0002 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "rentalvehicle.h" 0008 #include "datatypes_p.h" 0009 #include "json_p.h" 0010 0011 #include <QMetaEnum> 0012 0013 using namespace KPublicTransport; 0014 0015 namespace KPublicTransport { 0016 class RentalVehicleNetworkPrivate : public QSharedData 0017 { 0018 public: 0019 QString name; 0020 RentalVehicle::VehicleTypes vehicleTypes = RentalVehicle::Unknown; 0021 }; 0022 0023 class RentalVehicleStationPrivate : public QSharedData 0024 { 0025 public: 0026 int availableVehicles = -1; 0027 int capacity = -1; 0028 RentalVehicleNetwork network; 0029 std::vector<int> capacities; 0030 std::vector<int> availabilities; 0031 }; 0032 0033 class RentalVehiclePrivate : public QSharedData 0034 { 0035 public: 0036 RentalVehicle::VehicleType type = RentalVehicle::Unknown; 0037 int remainingRange = -1; 0038 KPublicTransport::RentalVehicleNetwork network; 0039 }; 0040 } 0041 0042 KPUBLICTRANSPORT_MAKE_GADGET(RentalVehicleNetwork) 0043 KPUBLICTRANSPORT_MAKE_PROPERTY(RentalVehicleNetwork, QString, name, setName) 0044 KPUBLICTRANSPORT_MAKE_PROPERTY(RentalVehicleNetwork, RentalVehicle::VehicleTypes, vehicleTypes, setVehicleTypes) 0045 0046 bool RentalVehicleNetwork::isValid() const 0047 { 0048 return !d->name.isEmpty(); 0049 } 0050 0051 /** Checks if two instances refer to the same network. */ 0052 bool RentalVehicleNetwork::isSame(const RentalVehicleNetwork &lhs, const RentalVehicleNetwork &rhs) 0053 { 0054 return lhs.name() == rhs.name(); 0055 } 0056 0057 QJsonObject RentalVehicleNetwork::toJson(const RentalVehicleNetwork &network) 0058 { 0059 return Json::toJson(network); 0060 } 0061 0062 RentalVehicleNetwork RentalVehicleNetwork::fromJson(const QJsonObject &obj) 0063 { 0064 return Json::fromJson<RentalVehicleNetwork>(obj); 0065 } 0066 0067 KPUBLICTRANSPORT_MAKE_GADGET(RentalVehicleStation) 0068 KPUBLICTRANSPORT_MAKE_PROPERTY(RentalVehicleStation, int, availableVehicles, setAvailableVehicles) 0069 KPUBLICTRANSPORT_MAKE_PROPERTY(RentalVehicleStation, int, capacity, setCapacity) 0070 KPUBLICTRANSPORT_MAKE_PROPERTY(RentalVehicleStation, RentalVehicleNetwork, network, setNetwork) 0071 0072 bool RentalVehicleStation::isValid() const 0073 { 0074 return d->network.isValid() || d->capacity >= 0 || d->availableVehicles >= 0; 0075 } 0076 0077 RentalVehicle::VehicleTypes RentalVehicleStation::supportedVehicleTypes() const 0078 { 0079 RentalVehicle::VehicleTypes types = {}; 0080 const auto me = QMetaEnum::fromType<RentalVehicle::VehicleType>(); 0081 for (auto i = 0; i < me.keyCount() && i < (int)d->capacities.size(); ++i) { 0082 if (d->capacities[i] >= 0) { 0083 types |= (RentalVehicle::VehicleType)me.value(i); 0084 } 0085 } 0086 return types | availableVehicleTypes(); 0087 } 0088 0089 RentalVehicle::VehicleTypes KPublicTransport::RentalVehicleStation::availableVehicleTypes() const 0090 { 0091 RentalVehicle::VehicleTypes types = {}; 0092 const auto me = QMetaEnum::fromType<RentalVehicle::VehicleType>(); 0093 for (auto i = 0; i < me.keyCount() && i < (int)d->availabilities.size(); ++i) { 0094 if (d->availabilities[i] >= 0) { 0095 types |= (RentalVehicle::VehicleType)me.value(i); 0096 } 0097 } 0098 return types; 0099 } 0100 0101 int RentalVehicleStation::capacity(RentalVehicle::VehicleType type) const 0102 { 0103 const auto me = QMetaEnum::fromType<RentalVehicle::VehicleType>(); 0104 for (auto i = 0; i < me.keyCount() && i < (int)d->capacities.size(); ++i) { 0105 if (me.value(i) == type) { 0106 return d->capacities[i]; 0107 } 0108 } 0109 return -1; 0110 } 0111 0112 void RentalVehicleStation::setCapacity(RentalVehicle::VehicleType type, int capacity) 0113 { 0114 const auto me = QMetaEnum::fromType<RentalVehicle::VehicleType>(); 0115 for (auto i = 0; i < me.keyCount(); ++i) { 0116 if (me.value(i) != type) { 0117 continue; 0118 } 0119 d->capacities.resize(std::max(d->capacities.size(), (std::size_t)(i + 1)), -1); 0120 d->capacities[i] = capacity; 0121 return; 0122 } 0123 } 0124 0125 int RentalVehicleStation::availableVehicles(RentalVehicle::VehicleType type) const 0126 { 0127 const auto me = QMetaEnum::fromType<RentalVehicle::VehicleType>(); 0128 for (auto i = 0; i < me.keyCount() && i < (int)d->availabilities.size(); ++i) { 0129 if (me.value(i) == type) { 0130 return d->availabilities[i]; 0131 } 0132 } 0133 return -1; 0134 } 0135 0136 void RentalVehicleStation::setAvailableVehicles(RentalVehicle::VehicleType type, int count) 0137 { 0138 const auto me = QMetaEnum::fromType<RentalVehicle::VehicleType>(); 0139 for (auto i = 0; i < me.keyCount(); ++i) { 0140 if (me.value(i) != type) { 0141 continue; 0142 } 0143 d->availabilities.resize(std::max(d->availabilities.size(), (std::size_t)(i + 1)), -1); 0144 d->availabilities[i] = count; 0145 return; 0146 } 0147 } 0148 0149 bool RentalVehicleStation::isSame(const RentalVehicleStation &lhs, const RentalVehicleStation &rhs) 0150 { 0151 return RentalVehicleNetwork::isSame(lhs.network(), rhs.network()); 0152 } 0153 0154 static QJsonValue typeVectorToJson(const std::vector<int> &v) 0155 { 0156 if (v.empty()) { 0157 return {}; 0158 } 0159 QJsonObject obj; 0160 const auto me = QMetaEnum::fromType<RentalVehicle::VehicleType>(); 0161 for (auto i = 0; i < me.keyCount() && i < (int)v.size(); ++i) { 0162 if (v[i] < 0) { 0163 continue; 0164 } 0165 obj.insert(QLatin1String(me.key(i)), v[i]); 0166 } 0167 return obj.isEmpty() ? QJsonValue() : obj; 0168 } 0169 0170 QJsonObject RentalVehicleStation::toJson(const RentalVehicleStation &station) 0171 { 0172 auto obj = Json::toJson(station); 0173 if (station.network().isValid()) { 0174 obj.insert(QLatin1String("network"), RentalVehicleNetwork::toJson(station.network())); 0175 } 0176 auto v = typeVectorToJson(station.d->capacities); 0177 if (v.isObject()) { 0178 obj.insert(QLatin1String("capacitiesByType"), v); 0179 } 0180 v = typeVectorToJson(station.d->availabilities); 0181 if (v.isObject()) { 0182 obj.insert(QLatin1String("availabilitiesByType"), v); 0183 } 0184 return obj; 0185 } 0186 0187 static std::vector<int> typeVectorFromJson(const QJsonValue &v) 0188 { 0189 std::vector<int> out; 0190 const auto obj = v.toObject(); 0191 if (obj.isEmpty()) { 0192 return out; 0193 } 0194 0195 const auto me = QMetaEnum::fromType<RentalVehicle::VehicleType>(); 0196 for (auto i = 0; i < me.keyCount(); ++i) { 0197 const auto it = obj.find(QLatin1String(me.key(i))); 0198 if (it == obj.end()) { 0199 continue; 0200 } 0201 out.resize(i + 1, -1); 0202 out[i] = it.value().toInt(); 0203 } 0204 0205 return out; 0206 } 0207 0208 RentalVehicleStation RentalVehicleStation::fromJson(const QJsonObject &obj) 0209 { 0210 auto station = Json::fromJson<RentalVehicleStation>(obj); 0211 station.setNetwork(RentalVehicleNetwork::fromJson(obj.value(QLatin1String("network")).toObject())); 0212 station.d->capacities = typeVectorFromJson(obj.value(QLatin1String("capacitiesByType"))); 0213 station.d->availabilities = typeVectorFromJson(obj.value(QLatin1String("availabilitiesByType"))); 0214 return station; 0215 } 0216 0217 KPUBLICTRANSPORT_MAKE_GADGET(RentalVehicle) 0218 KPUBLICTRANSPORT_MAKE_PROPERTY(RentalVehicle, RentalVehicle::VehicleType, type, setType) 0219 KPUBLICTRANSPORT_MAKE_PROPERTY(RentalVehicle, int, remainingRange, setRemainingRange) 0220 KPUBLICTRANSPORT_MAKE_PROPERTY(RentalVehicle, RentalVehicleNetwork, network, setNetwork) 0221 0222 QJsonObject RentalVehicle::toJson(const RentalVehicle &vehicle) 0223 { 0224 auto obj = Json::toJson(vehicle); 0225 if (vehicle.d->remainingRange < 0) { 0226 obj.remove(QLatin1String("remainingRange")); 0227 } 0228 if (vehicle.network().isValid()) { 0229 obj.insert(QLatin1String("network"), RentalVehicleNetwork::toJson(vehicle.network())); 0230 } 0231 return obj; 0232 } 0233 0234 RentalVehicle RentalVehicle::fromJson(const QJsonObject &obj) 0235 { 0236 auto v = Json::fromJson<RentalVehicle>(obj); 0237 v.setNetwork(RentalVehicleNetwork::fromJson(obj.value(QLatin1String("network")).toObject())); 0238 return v; 0239 } 0240 0241 #include "moc_rentalvehicle.cpp"