summaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
authorarkady-e1ppa <[email protected]>2024-11-29 22:02:21 +0300
committerarkady-e1ppa <[email protected]>2024-11-29 22:12:26 +0300
commitb21317884da9622ac16bbad26627ae014d72d6a7 (patch)
tree1af2253192c15fba295fdde1d23d6c7fc6792401 /library/cpp
parent0924e1c53b7aec2c5efefe89499154b0a7e902f7 (diff)
YT-21233: Introduce ToAttributeValue cpo which removes dependency of TErrorAttribute from yt/core
Plan: 1) Remove `IAttributedDictionary` type from the public API. \+ 2) Remove `Set` method from public API in favor of `operator<<=`. \+ 3) Adopt `ConvertTo<T>` (or other name) CPO with proper extension into `NYT::NYson::ConvertTo` from `yt/core`. 4) Use CPO from (3) to eliminate direct dependency on `yt/core` of `Get/Find` methods from attributes API. 5) Adopt `ConvertToYsonString` (or other name) CPO with proper extension into `yt/core` customisations. 6) Use CPO from (5) to eliminate direct dependency on `yt/core` of `TErrorAttribute` ctor. 7) Swap attributes implementation to the one which doesn’t use `IAttributeDictionary`. 8) At this point `stripped_error*` can be moved to library/cpp/yt and so can recursively dependant on THROW macro methods `Get/Find/…`. 9) Adjust CPO’s to work with `std::string` instead of `TYsonString` assuming text format to be used (maybe `TString` for now). 10) Remove dep of `library/cpp/yt/error` on `yson` entirely. This pr addresses 5-6 steps of plan. Below is a brief explanation of design decisions. We also expressed everything related to key-value code in terms of aliases of `TErrorAttribute` so that later we could make a relatively simple switch to `std::string`. We expect to do steps 7-8 in the next pull request as everything should be ready commit_hash:de9feca2bd24d823b33d904ef0fa5f4856f9b020
Diffstat (limited to 'library/cpp')
-rw-r--r--library/cpp/yt/error/convert_to_cpo.h4
-rw-r--r--library/cpp/yt/error/error_attribute.h57
-rw-r--r--library/cpp/yt/error/error_attributes-inl.h18
-rw-r--r--library/cpp/yt/error/error_attributes.cpp2
-rw-r--r--library/cpp/yt/error/error_attributes.h35
-rw-r--r--library/cpp/yt/error/mergeable_dictionary.h6
-rw-r--r--library/cpp/yt/error/public.h2
7 files changed, 92 insertions, 32 deletions
diff --git a/library/cpp/yt/error/convert_to_cpo.h b/library/cpp/yt/error/convert_to_cpo.h
index 55f608c3b60..dcfc8b0677d 100644
--- a/library/cpp/yt/error/convert_to_cpo.h
+++ b/library/cpp/yt/error/convert_to_cpo.h
@@ -2,8 +2,6 @@
#include <library/cpp/yt/misc/tag_invoke_cpo.h>
-#include <util/generic/strbuf.h>
-
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
@@ -34,7 +32,7 @@ inline constexpr NConvertToImpl::TFn<T> ConvertTo = {};
////////////////////////////////////////////////////////////////////////////////
template <class TTo, class TFrom>
-concept CConvertToWorks = requires (const TFrom& from) {
+concept CConvertsTo = requires (const TFrom& from) {
{ NYT::ConvertTo<TTo>(from) } -> std::same_as<TTo>;
};
diff --git a/library/cpp/yt/error/error_attribute.h b/library/cpp/yt/error/error_attribute.h
new file mode 100644
index 00000000000..dec4a4dd9b3
--- /dev/null
+++ b/library/cpp/yt/error/error_attribute.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <library/cpp/yt/misc/tag_invoke_cpo.h>
+
+// TODO(arkady-e1ppa): Eliminate.
+#include <library/cpp/yt/yson_string/string.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NToAttributeValueImpl {
+
+struct TFn
+ : public TTagInvokeCpoBase<TFn>
+{ };
+
+} // namespace NToAttributeValueImpl
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline constexpr NToAttributeValueImpl::TFn ToAttributeValue = {};
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+concept CConvertibleToAttributeValue = CTagInvocableS<
+ TTagInvokeTag<ToAttributeValue>,
+ NYson::TYsonString(const T&)>;
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TErrorAttribute
+{
+ // NB(arkady-e1ppa): Switch to std::string is quite possible
+ // however it requires patching IAttributeDictionary or
+ // switching it to the std::string first for interop reasons.
+ // Do that later.
+ using TKey = TString;
+ // TODO(arkady-e1ppa): Use ConvertToYsonString(value, Format::Text)
+ // here for complex values. Write manual implementations as ToString
+ // for primitive types (e.g. integral types, guid, string, time).
+ using TValue = NYson::TYsonString;
+
+ template <CConvertibleToAttributeValue T>
+ TErrorAttribute(const TKey& key, const T& value)
+ : Key(key)
+ , Value(NYT::ToAttributeValue(value))
+ { }
+
+ TKey Key;
+ TValue Value;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/error/error_attributes-inl.h b/library/cpp/yt/error/error_attributes-inl.h
index 8ffbf3e0a39..6574665865b 100644
--- a/library/cpp/yt/error/error_attributes-inl.h
+++ b/library/cpp/yt/error/error_attributes-inl.h
@@ -9,7 +9,7 @@ namespace NYT {
////////////////////////////////////////////////////////////////////////////////
template <class T>
- requires CConvertToWorks<T, TErrorAttributes::TValue>
+ requires CConvertsTo<T, TErrorAttributes::TValue>
T TErrorAttributes::Get(TStringBuf key) const
{
auto yson = GetYson(key);
@@ -21,7 +21,7 @@ T TErrorAttributes::Get(TStringBuf key) const
}
template <class T>
- requires CConvertToWorks<T, TErrorAttributes::TValue>
+ requires CConvertsTo<T, TErrorAttributes::TValue>
typename TOptionalTraits<T>::TOptional TErrorAttributes::Find(TStringBuf key) const
{
auto yson = FindYson(key);
@@ -36,8 +36,8 @@ typename TOptionalTraits<T>::TOptional TErrorAttributes::Find(TStringBuf key) co
}
template <class T>
- requires CConvertToWorks<T, TErrorAttributes::TValue>
-T TErrorAttributes::GetAndRemove(const TString& key)
+ requires CConvertsTo<T, TErrorAttributes::TValue>
+T TErrorAttributes::GetAndRemove(const TKey& key)
{
auto result = Get<T>(key);
Remove(key);
@@ -45,15 +45,15 @@ T TErrorAttributes::GetAndRemove(const TString& key)
}
template <class T>
- requires CConvertToWorks<T, TErrorAttributes::TValue>
+ requires CConvertsTo<T, TErrorAttributes::TValue>
T TErrorAttributes::Get(TStringBuf key, const T& defaultValue) const
{
return Find<T>(key).value_or(defaultValue);
}
template <class T>
- requires CConvertToWorks<T, TErrorAttributes::TValue>
-T TErrorAttributes::GetAndRemove(const TString& key, const T& defaultValue)
+ requires CConvertsTo<T, TErrorAttributes::TValue>
+T TErrorAttributes::GetAndRemove(const TKey& key, const T& defaultValue)
{
auto result = Find<T>(key);
if (result) {
@@ -65,8 +65,8 @@ T TErrorAttributes::GetAndRemove(const TString& key, const T& defaultValue)
}
template <class T>
- requires CConvertToWorks<T, TErrorAttributes::TValue>
-typename TOptionalTraits<T>::TOptional TErrorAttributes::FindAndRemove(const TString& key)
+ requires CConvertsTo<T, TErrorAttributes::TValue>
+typename TOptionalTraits<T>::TOptional TErrorAttributes::FindAndRemove(const TKey& key)
{
auto result = Find<T>(key);
if (result) {
diff --git a/library/cpp/yt/error/error_attributes.cpp b/library/cpp/yt/error/error_attributes.cpp
index 2c1b5423146..09aa48eebb9 100644
--- a/library/cpp/yt/error/error_attributes.cpp
+++ b/library/cpp/yt/error/error_attributes.cpp
@@ -15,7 +15,7 @@ void TErrorAttributes::Clear()
}
}
-NYson::TYsonString TErrorAttributes::GetYsonAndRemove(const TString& key)
+TErrorAttributes::TValue TErrorAttributes::GetYsonAndRemove(const TKey& key)
{
auto result = GetYson(key);
Remove(key);
diff --git a/library/cpp/yt/error/error_attributes.h b/library/cpp/yt/error/error_attributes.h
index 7c2f4a54078..80dd80de484 100644
--- a/library/cpp/yt/error/error_attributes.h
+++ b/library/cpp/yt/error/error_attributes.h
@@ -1,6 +1,7 @@
#pragma once
#include "convert_to_cpo.h"
+#include "error_attribute.h"
#include "mergeable_dictionary.h"
#include <library/cpp/yt/misc/optional.h>
@@ -20,34 +21,34 @@ namespace NYT {
class TErrorAttributes
{
public:
- using TKey = TString;
- using TValue = NYson::TYsonString;
+ using TKey = TErrorAttribute::TKey;
+ using TValue = TErrorAttribute::TValue;
using TKeyValuePair = std::pair<TKey, TValue>;
//! Returns the list of all keys in the dictionary.
- std::vector<TString> ListKeys() const;
+ std::vector<TKey> ListKeys() const;
//! Returns the list of all key-value pairs in the dictionary.
std::vector<TKeyValuePair> ListPairs() const;
//! Returns the value of the attribute (null indicates that the attribute is not found).
- NYson::TYsonString FindYson(TStringBuf key) const;
+ TValue FindYson(TStringBuf key) const;
//! Sets the value of the attribute.
- void SetYson(const TString& key, const NYson::TYsonString& value);
+ void SetYson(const TKey& key, const TValue& value);
//! Removes the attribute.
//! Returns |true| if the attribute was removed or |false| if there is no attribute with this key.
- bool Remove(const TString& key);
+ bool Remove(const TKey& key);
//! Removes all attributes.
void Clear();
//! Returns the value of the attribute (throws an exception if the attribute is not found).
- NYson::TYsonString GetYson(TStringBuf key) const;
+ TValue GetYson(TStringBuf key) const;
//! Same as #GetYson but removes the value.
- NYson::TYsonString GetYsonAndRemove(const TString& key);
+ TValue GetYsonAndRemove(const TKey& key);
//! Returns |true| iff the given key is present.
bool Contains(TStringBuf key) const;
@@ -58,35 +59,35 @@ public:
//! Finds the attribute and deserializes its value.
//! Throws if no such value is found.
template <class T>
- requires CConvertToWorks<T, TValue>
+ requires CConvertsTo<T, TValue>
T Get(TStringBuf key) const;
//! Same as #Get but removes the value.
template <class T>
- requires CConvertToWorks<T, TValue>
- T GetAndRemove(const TString& key);
+ requires CConvertsTo<T, TValue>
+ T GetAndRemove(const TKey& key);
//! Finds the attribute and deserializes its value.
//! Uses default value if no such attribute is found.
template <class T>
- requires CConvertToWorks<T, TValue>
+ requires CConvertsTo<T, TValue>
T Get(TStringBuf key, const T& defaultValue) const;
//! Same as #Get but removes the value if it exists.
template <class T>
- requires CConvertToWorks<T, TValue>
- T GetAndRemove(const TString& key, const T& defaultValue);
+ requires CConvertsTo<T, TValue>
+ T GetAndRemove(const TKey& key, const T& defaultValue);
//! Finds the attribute and deserializes its value.
//! Returns null if no such attribute is found.
template <class T>
- requires CConvertToWorks<T, TValue>
+ requires CConvertsTo<T, TValue>
typename TOptionalTraits<T>::TOptional Find(TStringBuf key) const;
//! Same as #Find but removes the value if it exists.
template <class T>
- requires CConvertToWorks<T, TValue>
- typename TOptionalTraits<T>::TOptional FindAndRemove(const TString& key);
+ requires CConvertsTo<T, TValue>
+ typename TOptionalTraits<T>::TOptional FindAndRemove(const TKey& key);
template <CMergeableDictionary TDictionary>
void MergeFrom(const TDictionary& dict);
diff --git a/library/cpp/yt/error/mergeable_dictionary.h b/library/cpp/yt/error/mergeable_dictionary.h
index 90597059e40..361694d8416 100644
--- a/library/cpp/yt/error/mergeable_dictionary.h
+++ b/library/cpp/yt/error/mergeable_dictionary.h
@@ -1,6 +1,7 @@
#pragma once
#include "public.h"
+#include "error_attribute.h"
#include <ranges>
@@ -23,6 +24,7 @@ namespace NDetail {
template <class T>
struct TMergeableDictionaryImpl
{
+ // TL;DR: MakeIterableView returns something like std::span<std::pair<TKey, TValue>>.
using TView = std::invoke_result_t<decltype(&TMergeDictionariesTraits<T>::MakeIterableView), const T&>;
using TIterator = std::ranges::iterator_t<TView>;
using TValue = typename std::iterator_traits<TIterator>::value_type;
@@ -33,10 +35,10 @@ struct TMergeableDictionaryImpl
static constexpr bool CorrectTupleElements = requires {
typename std::tuple_element<0, TValue>::type;
- std::same_as<typename std::tuple_element<0, TValue>::type, TString>;
+ std::same_as<typename std::tuple_element<0, TValue>::type, TErrorAttribute::TKey>;
typename std::tuple_element<1, TValue>::type;
- std::same_as<typename std::tuple_element<1, TValue>::type, NYson::TYsonString>;
+ std::same_as<typename std::tuple_element<1, TValue>::type, TErrorAttribute::TValue>;
};
};
diff --git a/library/cpp/yt/error/public.h b/library/cpp/yt/error/public.h
index 63b95497c7b..04201128aa3 100644
--- a/library/cpp/yt/error/public.h
+++ b/library/cpp/yt/error/public.h
@@ -9,6 +9,8 @@ namespace NYT {
template <class T>
class TErrorOr;
+
+struct TErrorAttribute;
class TErrorAttributes;
struct TOriginAttributes;