|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2022 - Raw Material Software Limited
-
- JUCE is an open source library subject to commercial or open-source
- licensing.
-
- By using JUCE, you agree to the terms of both the JUCE 7 End-User License
- Agreement and JUCE Privacy Policy.
-
- End User License Agreement: www.juce.com/juce-7-licence
- Privacy Policy: www.juce.com/juce-privacy-policy
-
- Or: You may also use this code under the terms of the GPL v3 (see
- www.gnu.org/licenses).
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
- namespace juce::midi_ci
- {
-
- struct PropertyDelegateDetail
- {
- /*
- Note: We don't use ToVar and FromVar here, because we want to omit fields that are using
- their default values.
- */
-
- template <typename Target>
- static Target parseTargetHeader (const var& v,
- const std::map<Identifier, void (*) (Target&, const var&)>& parsers)
- {
- Target target;
-
- if (auto* obj = v.getDynamicObject())
- {
- for (const auto& pair : obj->getProperties())
- {
- const auto parserIter = parsers.find (pair.name);
-
- if (parserIter != parsers.end())
- parserIter->second (target, pair.value);
- else
- target.extended[pair.name] = pair.value;
- }
- }
-
- return target;
- }
-
- static auto getParsersForPropertyReplyHeader()
- {
- using Target = PropertyReplyHeader;
- std::map<Identifier, void (*) (Target& header, const var& v)> map;
-
- map.emplace ("status", [] (Target& header, const var& v) { header.status = v; });
- map.emplace ("message", [] (Target& header, const var& v) { header.message = v; });
- map.emplace ("cacheTime", [] (Target& header, const var& v) { header.cacheTime = v; });
- map.emplace ("mediaType", [] (Target& header, const var& v) { header.mediaType = v; });
- map.emplace ("mutualEncoding", [] (Target& header, const var& v)
- {
- header.mutualEncoding = EncodingUtils::toEncoding (v.toString().toRawUTF8()).value_or (Encoding::ascii);
- });
-
- return map;
- }
-
- template <typename Target>
- static auto getParsersForGenericPropertyRequestHeader()
- {
- std::map<Identifier, void (*) (Target& header, const var& v)> map;
-
- map.emplace ("resource", [] (Target& header, const var& v) { header.resource = v; });
- map.emplace ("resId", [] (Target& header, const var& v) { header.resId = v; });
- map.emplace ("mediaType", [] (Target& header, const var& v) { header.mediaType = v; });
- map.emplace ("mutualEncoding", [] (Target& header, const var& v)
- {
- header.mutualEncoding = EncodingUtils::toEncoding (v.toString().toRawUTF8()).value_or (Encoding::ascii);
- });
-
- return map;
- }
-
- static auto getParsersForPropertyRequestHeader()
- {
- auto map = getParsersForGenericPropertyRequestHeader<PropertyRequestHeader>();
- map.emplace ("setPartial", [] (PropertyRequestHeader& header, const var& v) { header.setPartial = v; });
- map.emplace ("offset", [] (PropertyRequestHeader& header, const var& v)
- {
- if (! header.pagination.has_value())
- header.pagination = Pagination{};
-
- header.pagination->offset = v;
- });
- map.emplace ("limit", [] (PropertyRequestHeader& header, const var& v)
- {
- if (! header.pagination.has_value())
- header.pagination = Pagination{};
-
- header.pagination->limit = v;
- });
- return map;
- }
-
- static auto getParsersForPropertySubscriptionHeader()
- {
- auto map = getParsersForGenericPropertyRequestHeader<PropertySubscriptionHeader>();
-
- map.emplace ("subscribeId", [] (PropertySubscriptionHeader& header, const var& v) { header.subscribeId = v; });
- map.emplace ("command", [] (PropertySubscriptionHeader& header, const var& v)
- {
- header.command = [&]
- {
- if (v == "start")
- return PropertySubscriptionCommand::start;
-
- if (v == "partial")
- return PropertySubscriptionCommand::partial;
-
- if (v == "full")
- return PropertySubscriptionCommand::full;
-
- if (v == "notify")
- return PropertySubscriptionCommand::notify;
-
- if (v == "end")
- return PropertySubscriptionCommand::end;
-
- return PropertySubscriptionCommand::notify;
- }();
- });
-
- return map;
- }
-
- static auto getSetPartial (const PropertySubscriptionHeader&) { return false; }
- static auto getSetPartial (const PropertyRequestHeader& h) { return h.setPartial; }
- static auto getSetPartial (const PropertyReplyHeader&) { return false; }
-
- static auto getPagination (const PropertySubscriptionHeader&) { return std::optional<Pagination>{}; }
- static auto getPagination (const PropertyRequestHeader& h) { return h.pagination; }
- static auto getPagination (const PropertyReplyHeader&) { return std::optional<Pagination>{}; }
-
- static auto getCacheTime (const PropertySubscriptionHeader&) { return 0; }
- static auto getCacheTime (const PropertyRequestHeader&) { return 0; }
- static auto getCacheTime (const PropertyReplyHeader& h) { return h.cacheTime; }
-
- static auto getMessage (const PropertySubscriptionHeader&) { return String{}; }
- static auto getMessage (const PropertyRequestHeader&) { return String{}; }
- static auto getMessage (const PropertyReplyHeader& h) { return h.message; }
-
- static auto getResource (const PropertySubscriptionHeader& h) { return h.resource; }
- static auto getResource (const PropertyRequestHeader& h) { return h.resource; }
- static auto getResource (const PropertyReplyHeader&) { return String{}; }
-
- static auto getResId (const PropertySubscriptionHeader& h) { return h.resId; }
- static auto getResId (const PropertyRequestHeader& h) { return h.resId; }
- static auto getResId (const PropertyReplyHeader&) { return String{}; }
-
- static auto getCommand (const PropertySubscriptionHeader& h) { return h.command; }
- static auto getCommand (const PropertyRequestHeader&) { return PropertySubscriptionCommand{}; }
- static auto getCommand (const PropertyReplyHeader&) { return PropertySubscriptionCommand{}; }
-
- static auto getSubscribeId (const PropertySubscriptionHeader& h) { return h.subscribeId; }
- static auto getSubscribeId (const PropertyRequestHeader&) { return String{}; }
- static auto getSubscribeId (const PropertyReplyHeader&) { return String{}; }
-
- static std::optional<int> getStatus (const PropertySubscriptionHeader&) { return {}; }
- static std::optional<int> getStatus (const PropertyRequestHeader&) { return {}; }
- static std::optional<int> getStatus (const PropertyReplyHeader& h) { return h.status; }
-
- template <typename T>
- static auto toFieldsFromHeader (const T& t)
- {
- auto fields = t.extended;
-
- // Status shall always be included if it is present in the header
- if (const auto status = getStatus (t))
- fields["status"] = *status;
-
- if (getResource (t) != getResource (T()))
- fields["resource"] = getResource (t);
-
- if (getCommand (t) != getCommand (T()))
- fields["command"] = PropertySubscriptionCommandUtils::toString (getCommand (t));
-
- if (getSubscribeId (t) != getSubscribeId (T()))
- fields["subscribeId"] = getSubscribeId (t);
-
- if (getResId (t) != getResId (T()))
- fields["resId"] = getResId (t);
-
- if (t.mutualEncoding != T().mutualEncoding)
- fields["mutualEncoding"] = EncodingUtils::toString (t.mutualEncoding);
-
- if (t.mediaType != T().mediaType)
- fields["mediaType"] = t.mediaType;
-
- if (getSetPartial (t))
- fields["setPartial"] = true;
-
- if (getCacheTime (t) != getCacheTime (T()))
- fields["cacheTime"] = getCacheTime (t);
-
- if (getMessage (t) != getMessage (T()))
- fields["message"] = getMessage (t);
-
- if (const auto pagination = getPagination (t))
- {
- fields["offset"] = pagination->offset;
- fields["limit"] = pagination->limit;
- }
-
- return fields;
- }
- };
-
- //==============================================================================
- PropertySubscriptionHeader PropertySubscriptionHeader::parseCondensed (const var& v)
- {
- return PropertyDelegateDetail::parseTargetHeader (v, PropertyDelegateDetail::getParsersForPropertySubscriptionHeader());
- }
-
- var PropertySubscriptionHeader::toVarCondensed() const
- {
- return JSONUtils::makeObjectWithKeyFirst (PropertyDelegateDetail::toFieldsFromHeader (*this), "command");
- }
-
- PropertyRequestHeader PropertyRequestHeader::parseCondensed (const var& v)
- {
- return PropertyDelegateDetail::parseTargetHeader (v, PropertyDelegateDetail::getParsersForPropertyRequestHeader());
- }
-
- var PropertyRequestHeader::toVarCondensed() const
- {
- return JSONUtils::makeObjectWithKeyFirst (PropertyDelegateDetail::toFieldsFromHeader (*this), "resource");
- }
-
- PropertyReplyHeader PropertyReplyHeader::parseCondensed (const var& v)
- {
- return PropertyDelegateDetail::parseTargetHeader (v, PropertyDelegateDetail::getParsersForPropertyReplyHeader());
- }
-
- var PropertyReplyHeader::toVarCondensed() const
- {
- return JSONUtils::makeObjectWithKeyFirst (PropertyDelegateDetail::toFieldsFromHeader (*this), "status");
- }
-
- } // namespace juce::midi_ci
|