1 #pragma once
2 
3 #include "MCTPEndpoint.hpp"
4 
5 class MCTPDeviceRepository
6 {
7   private:
8     // FIXME: Ugh, hack. Figure out a better data structure?
9     std::map<std::string, std::shared_ptr<MCTPDevice>> devices;
10 
lookup(const std::shared_ptr<MCTPDevice> & device)11     auto lookup(const std::shared_ptr<MCTPDevice>& device)
12     {
13         auto pred = [&device](const auto& it) { return it.second == device; };
14         return std::ranges::find_if(devices, pred);
15     }
16 
17   public:
18     MCTPDeviceRepository() = default;
19     MCTPDeviceRepository(const MCTPDeviceRepository&) = delete;
20     MCTPDeviceRepository(MCTPDeviceRepository&&) = delete;
21     ~MCTPDeviceRepository() = default;
22 
23     MCTPDeviceRepository& operator=(const MCTPDeviceRepository&) = delete;
24     MCTPDeviceRepository& operator=(MCTPDeviceRepository&&) = delete;
25 
add(const std::string & inventory,const std::shared_ptr<MCTPDevice> & device)26     void add(const std::string& inventory,
27              const std::shared_ptr<MCTPDevice>& device)
28     {
29         auto [entry, fresh] = devices.emplace(inventory, device);
30         if (!fresh && entry->second.get() != device.get())
31         {
32             throw std::system_error(
33                 std::make_error_code(std::errc::device_or_resource_busy),
34                 std::format("Tried to add entry for existing device: {}",
35                             device->describe()));
36         }
37     }
38 
remove(const std::shared_ptr<MCTPDevice> & device)39     void remove(const std::shared_ptr<MCTPDevice>& device)
40     {
41         auto entry = lookup(device);
42         if (entry == devices.end())
43         {
44             throw std::system_error(
45                 std::make_error_code(std::errc::no_such_device),
46                 std::format("Trying to remove unknown device: {}",
47                             entry->second->describe()));
48         }
49         devices.erase(entry);
50     }
51 
contains(const std::shared_ptr<MCTPDevice> & device)52     bool contains(const std::shared_ptr<MCTPDevice>& device)
53     {
54         return lookup(device) != devices.end();
55     }
56 
57     std::optional<std::string>
inventoryFor(const std::shared_ptr<MCTPDevice> & device)58         inventoryFor(const std::shared_ptr<MCTPDevice>& device)
59     {
60         auto entry = lookup(device);
61         if (entry == devices.end())
62         {
63             return {};
64         }
65         return entry->first;
66     }
67 
deviceFor(const std::string & inventory)68     std::shared_ptr<MCTPDevice> deviceFor(const std::string& inventory)
69     {
70         auto entry = devices.find(inventory);
71         if (entry == devices.end())
72         {
73             return {};
74         }
75         return entry->second;
76     }
77 };
78