1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
JUCE/modules/juce_midi_ci/ci/juce_CIPropertyDelegate.cpp
2023-10-31 11:46:49 +00:00

255 lines
10 KiB
C++

/*
==============================================================================
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 auto getStatus (const PropertySubscriptionHeader&) { return 0; }
static auto getStatus (const PropertyRequestHeader&) { return 0; }
static auto getStatus (const PropertyReplyHeader& h) { return h.status; }
template <typename T>
static auto toFieldsFromHeader (const T& t)
{
auto fields = t.extended;
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 (getStatus (t) != getStatus (T()))
fields["status"] = getStatus (t);
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