mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-19 13:03:36 +00:00
ChargeSocketsHelper: implement a Diff method between old and new OSM keys
Signed-off-by: Séverin Lemaignan <severin@guakamole.org>
This commit is contained in:
@@ -47,6 +47,8 @@ std::string DebugPrint(char32_t * t) = delete;
|
|||||||
|
|
||||||
template <typename U, typename V>
|
template <typename U, typename V>
|
||||||
inline std::string DebugPrint(std::pair<U, V> const & p);
|
inline std::string DebugPrint(std::pair<U, V> const & p);
|
||||||
|
template <typename U, typename V, typename W>
|
||||||
|
inline std::string DebugPrint(std::tuple<U, V, W> const & p);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline std::string DebugPrint(std::list<T> const & v);
|
inline std::string DebugPrint(std::list<T> const & v);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -136,6 +138,14 @@ std::string DebugPrint(std::pair<U, V> const & p)
|
|||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename U, typename V, typename W>
|
||||||
|
std::string DebugPrint(std::tuple<U, V, W> const & p)
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "(" << DebugPrint(get<0>(p)) << ", " << DebugPrint(get<1>(p)) << ", " << DebugPrint(get<2>(p)) << ")";
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename IterT>
|
template <typename IterT>
|
||||||
std::string DebugPrintSequence(IterT beg, IterT end)
|
std::string DebugPrintSequence(IterT beg, IterT end)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -395,6 +395,35 @@ OSMKeyValues ChargeSocketsHelper::GetOSMKeyValues()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyValueDiffSet ChargeSocketsHelper::Diff(ChargeSocketDescriptors const & oldSockets)
|
||||||
|
{
|
||||||
|
KeyValueDiffSet result;
|
||||||
|
|
||||||
|
auto oldKeys = ChargeSocketsHelper(oldSockets).GetOSMKeyValues();
|
||||||
|
auto newKeys = GetOSMKeyValues();
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string> oldMap, newMap;
|
||||||
|
|
||||||
|
for (auto && [k, v] : oldKeys)
|
||||||
|
oldMap.emplace(k, v);
|
||||||
|
for (auto && [k, v] : newKeys)
|
||||||
|
newMap.emplace(k, v);
|
||||||
|
|
||||||
|
// Handle keys that exist in old
|
||||||
|
for (auto && [k, oldVal] : oldMap)
|
||||||
|
if (auto it = newMap.find(k); it == newMap.end())
|
||||||
|
result.insert({k, oldVal, ""}); // deleted
|
||||||
|
else if (it->second != oldVal)
|
||||||
|
result.insert({k, oldVal, it->second}); // updated
|
||||||
|
|
||||||
|
// Handle keys that are only new
|
||||||
|
for (auto && [k, newVal] : newMap)
|
||||||
|
if (!oldMap.contains(k))
|
||||||
|
result.insert({k, "", newVal}); // created
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void ChargeSocketsHelper::Sort()
|
void ChargeSocketsHelper::Sort()
|
||||||
{
|
{
|
||||||
size_t const unknownTypeOrder = SUPPORTED_TYPES.size();
|
size_t const unknownTypeOrder = SUPPORTED_TYPES.size();
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
#include <utility> // for std::pair
|
#include <utility> // for std::pair
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -19,11 +21,15 @@ typedef std::vector<ChargeSocketDescriptor> ChargeSocketDescriptors;
|
|||||||
|
|
||||||
typedef std::vector<std::pair<std::string, std::string>> OSMKeyValues;
|
typedef std::vector<std::pair<std::string, std::string>> OSMKeyValues;
|
||||||
|
|
||||||
|
typedef std::set<std::tuple<std::string, std::string, std::string>> KeyValueDiffSet;
|
||||||
|
|
||||||
class ChargeSocketsHelper
|
class ChargeSocketsHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChargeSocketsHelper() : m_dirty(false) {}
|
ChargeSocketsHelper() : m_dirty(false) {}
|
||||||
|
|
||||||
|
ChargeSocketsHelper(ChargeSocketDescriptors const & sockets) : m_chargeSockets(sockets), m_dirty(true) {}
|
||||||
|
|
||||||
/** Create a ChareSocketsHelper instance from an existing list of sockets
|
/** Create a ChareSocketsHelper instance from an existing list of sockets
|
||||||
* stored as "<type>|<nb>|[<power>];..."
|
* stored as "<type>|<nb>|[<power>];..."
|
||||||
*
|
*
|
||||||
@@ -91,6 +97,19 @@ public:
|
|||||||
"mcs", "type2_combo", "chademo", "nacs", "type1", "gb_dc",
|
"mcs", "type2_combo", "chademo", "nacs", "type1", "gb_dc",
|
||||||
"chaoji", "type3c", "type2_cable", "type2", "gb_ac", "type3a"};
|
"chaoji", "type3c", "type2_cable", "type2", "gb_ac", "type3a"};
|
||||||
|
|
||||||
|
/** Return a list of OSM attributes that have changed between the current
|
||||||
|
* list of sockets and the provided old list.
|
||||||
|
*
|
||||||
|
* Returns a set of (key, old_value, new_value) tuples.
|
||||||
|
*
|
||||||
|
* If old_value="", the attribute is new (ie has been created)
|
||||||
|
* If new_value="", the attribute has been deleted
|
||||||
|
*
|
||||||
|
* Note that this method is not const as it may trigger a re-ordering of the
|
||||||
|
* internal list of sockets.
|
||||||
|
*/
|
||||||
|
KeyValueDiffSet Diff(ChargeSocketDescriptors const & oldSockets);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ChargeSocketDescriptors m_chargeSockets;
|
ChargeSocketDescriptors m_chargeSockets;
|
||||||
|
|
||||||
|
|||||||
@@ -203,6 +203,52 @@ UNIT_TEST(ChargeSockets_Processing)
|
|||||||
TEST_EQUAL(
|
TEST_EQUAL(
|
||||||
ChargeSocketsHelper("type2|3|43;type2|5|7.4;type2_combo|10|250;type2|2|50;type2_combo|2|100").GetOSMKeyValues(),
|
ChargeSocketsHelper("type2|3|43;type2|5|7.4;type2_combo|10|250;type2|2|50;type2_combo|2|100").GetOSMKeyValues(),
|
||||||
kvs, ());
|
kvs, ());
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// OSM attribute diff
|
||||||
|
OSMKeyValues kvs_old, kvs_new;
|
||||||
|
KeyValueDiffSet diff;
|
||||||
|
|
||||||
|
kvs_old = {{"socket:type2", "2"}};
|
||||||
|
kvs_new = {{"socket:type2", "2"}};
|
||||||
|
diff = {};
|
||||||
|
TEST_EQUAL(FromKVs(kvs_new).Diff(FromKVs(kvs_old).GetSockets()), diff, ());
|
||||||
|
|
||||||
|
kvs_old = {{"socket:type2", "3"}};
|
||||||
|
kvs_new = {{"socket:type2", "2"}};
|
||||||
|
diff = {{"socket:type2", "3", "2"}};
|
||||||
|
TEST_EQUAL(FromKVs(kvs_new).Diff(FromKVs(kvs_old).GetSockets()), diff, ());
|
||||||
|
|
||||||
|
kvs_old = {{"socket:type2", "2"}};
|
||||||
|
kvs_new = {{"socket:type2", "3"}};
|
||||||
|
diff = {{"socket:type2", "2", "3"}};
|
||||||
|
TEST_EQUAL(FromKVs(kvs_new).Diff(FromKVs(kvs_old).GetSockets()), diff, ());
|
||||||
|
|
||||||
|
kvs_old = {};
|
||||||
|
kvs_new = {{"socket:type2", "2"}};
|
||||||
|
diff = {{"socket:type2", "", "2"}};
|
||||||
|
TEST_EQUAL(FromKVs(kvs_new).Diff(FromKVs(kvs_old).GetSockets()), diff, ());
|
||||||
|
|
||||||
|
kvs_old = {{"socket:type2", "2"}};
|
||||||
|
kvs_new = {};
|
||||||
|
diff = {{"socket:type2", "2", ""}};
|
||||||
|
TEST_EQUAL(FromKVs(kvs_new).Diff(FromKVs(kvs_old).GetSockets()), diff, ());
|
||||||
|
|
||||||
|
kvs_old = {{"socket:type2_combo", "10;2"},
|
||||||
|
{"socket:type2_combo:output", "250;100"},
|
||||||
|
{"socket:type1", "5"},
|
||||||
|
{"socket:type2", "2;3;5"},
|
||||||
|
{"socket:type2:output", "50;43;7.4"}};
|
||||||
|
kvs_new = {{"socket:type2_combo", "10;2"},
|
||||||
|
{"socket:type2_combo:output", "250;100"},
|
||||||
|
{"socket:chademo", "2"},
|
||||||
|
{"socket:type2", "2;3"},
|
||||||
|
{"socket:type2:output", "50;43"}};
|
||||||
|
diff = {{"socket:type1", "5", ""},
|
||||||
|
{"socket:type2", "2;3;5", "2;3"},
|
||||||
|
{"socket:type2:output", "50;43;7.4", "50;43"},
|
||||||
|
{"socket:chademo", "", "2"}};
|
||||||
|
TEST_EQUAL(FromKVs(kvs_new).Diff(FromKVs(kvs_old).GetSockets()), diff, ());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace feature_charge_sockets_test
|
} // namespace feature_charge_sockets_test
|
||||||
|
|||||||
Reference in New Issue
Block a user