szaszm commented on code in PR #1589:
URL: https://github.com/apache/nifi-minifi-cpp/pull/1589#discussion_r1263795580


##########
libminifi/include/core/ProcessContext.h:
##########
@@ -102,18 +103,44 @@ class ProcessContext : public 
controller::ControllerServiceLookup, public core::
     return value;
   }
 
+  template<typename T = std::string>
+  std::enable_if_t<std::is_default_constructible<T>::value, std::optional<T>>
+  getProperty(const PropertyReference& property) const {
+    T value;
+    try {
+      if (!getProperty(property.name, value)) return std::nullopt;
+    } catch (const utils::internal::ValueException&) {
+      return std::nullopt;
+    }
+    return value;
+  }
+
+  template<typename T>
+  requires(!std::is_convertible_v<T&, const FlowFile&> && 
!std::is_convertible_v<T&, const std::shared_ptr<FlowFile>&>)
+  bool getProperty(std::string_view name, T &value) const {

Review Comment:
   ```suggestion
     template<typename T>
     concept NotAFlowFile = !std::convertible_to<T&, const FlowFile&> && 
!std::convertible_to<T&, const std::shared_ptr<FlowFile>&>;
   
     bool getProperty(std::string_view name, NotAFlowFile auto& value) const {
   ```



##########
libminifi/include/core/ProcessContext.h:
##########
@@ -102,18 +103,44 @@ class ProcessContext : public 
controller::ControllerServiceLookup, public core::
     return value;
   }
 
+  template<typename T = std::string>
+  std::enable_if_t<std::is_default_constructible<T>::value, std::optional<T>>
+  getProperty(const PropertyReference& property) const {

Review Comment:
   Let's convert this to concept constraints, since we're touching it, and the 
new one below is also written like this.
   ```suggestion
     template<std::default_initializable T = std::string>
     std::optional<T> getProperty(const PropertyReference& property) const {
   ```



##########
libminifi/include/core/ProcessContext.h:
##########
@@ -102,18 +103,44 @@ class ProcessContext : public 
controller::ControllerServiceLookup, public core::
     return value;
   }
 
+  template<typename T = std::string>
+  std::enable_if_t<std::is_default_constructible<T>::value, std::optional<T>>
+  getProperty(const PropertyReference& property) const {
+    T value;
+    try {
+      if (!getProperty(property.name, value)) return std::nullopt;
+    } catch (const utils::internal::ValueException&) {
+      return std::nullopt;
+    }
+    return value;
+  }
+
+  template<typename T>
+  requires(!std::is_convertible_v<T&, const FlowFile&> && 
!std::is_convertible_v<T&, const std::shared_ptr<FlowFile>&>)
+  bool getProperty(std::string_view name, T &value) const {
+    return getPropertyImp<typename 
std::common_type<T>::type>(std::string{name}, value);
+  }
+
   template<typename T>
-  std::enable_if_t<!std::is_convertible_v<T&, const FlowFile&> && 
!std::is_convertible_v<T&, const std::shared_ptr<FlowFile>&>,
-      bool> getProperty(const std::string &name, T &value) const {
-    return getPropertyImp<typename std::common_type<T>::type>(name, value);
+  requires(!std::is_convertible_v<T&, const FlowFile&> && 
!std::is_convertible_v<T&, const std::shared_ptr<FlowFile>&>)
+  bool getProperty(const PropertyReference& property, T &value) const {

Review Comment:
   ```suggestion
     bool getProperty(const PropertyReference& property, NotAFlowFile auto& 
value) const {
   ```



##########
libminifi/src/core/Property.cpp:
##########
@@ -90,4 +94,41 @@ std::vector<std::pair<std::string, std::string>> 
Property::getExclusiveOfPropert
   return exclusive_of_properties_;
 }
 
+namespace {
+std::vector<PropertyValue> createPropertyValues(gsl::span<const 
std::string_view> values, const core::PropertyParser& property_parser) {
+  return ranges::views::transform(values, [&property_parser](const auto& 
value) {
+    return property_parser.parse(value);
+  }) | ranges::to<std::vector>;
+}
+
+inline std::vector<std::string> createStrings(gsl::span<const 
std::string_view> string_views) {
+  return ranges::views::transform(string_views, [](const auto& string_view) { 
return std::string{string_view}; })
+      | ranges::to<std::vector>;
+}
+
+inline std::vector<std::pair<std::string, std::string>> 
createStrings(gsl::span<const std::pair<std::string_view, std::string_view>> 
pairs_of_string_views) {
+  return ranges::views::transform(pairs_of_string_views, [](const auto& 
pair_of_string_views) { return std::pair<std::string, 
std::string>(pair_of_string_views); })
+      | ranges::to<std::vector>;
+}
+}  // namespace
+
+Property::Property(const PropertyReference& compile_time_property)
+    : name_(compile_time_property.name),
+      description_(compile_time_property.description),
+      is_required_(compile_time_property.is_required),
+      valid_regex_(compile_time_property.valid_regex),

Review Comment:
   Is this `valid_regex_` ever used? The builder doesn't seem to set it. If 
it's always empty, we might as well drop it.



##########
libminifi/include/core/PropertyType.h:
##########
@@ -90,12 +47,19 @@ class PropertyValidator {
   [[nodiscard]] virtual ValidationResult validate(const std::string &subject, 
const std::shared_ptr<minifi::state::response::Value> &input) const = 0;
 
   [[nodiscard]] virtual ValidationResult validate(const std::string &subject, 
const std::string &input) const = 0;
+};
+
+class PropertyType : public PropertyParser, public PropertyValidator {

Review Comment:
   I think composition would be better design here, than multiple inheritance.
   
   Most property types have names changed to end with "_TYPE", except 
`UnsignedIntPropertyType`. This particular case may be an oversight.
   
   But the pattern ultimately overrides the `getName` method of 
`PropertyValidator`, so it should retuirn a validator name (like the old 
version), but a method called `getName` in `PropertyType` has no business 
returning a validator name. I'm also not sure how the type name gets converted 
back to a validator name when used with a validator-aware C2 server.



##########
libminifi/test/unit/CoreTests.cpp:
##########
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../Catch.h"
+#include "core/Core.h"
+
+namespace org::apache::nifi::minifi::test {
+
+struct DummyStruct {};
+class DummyClass {};
+template<typename T> struct DummyStructTemplate {};
+template<typename T> class DummyClassTemplate {};
+
+TEST_CASE("getClassName() works correctly") {
+  CHECK(core::getClassName<DummyStruct>() == 
"org::apache::nifi::minifi::test::DummyStruct");
+  CHECK(core::getClassName<DummyClass>() == 
"org::apache::nifi::minifi::test::DummyClass");
+  CHECK(core::getClassName<DummyStructTemplate<int>>() == 
"org::apache::nifi::minifi::test::DummyStructTemplate<int>");
+  CHECK(core::getClassName<DummyClassTemplate<int>>() == 
"org::apache::nifi::minifi::test::DummyClassTemplate<int>");
+}
+
+TEST_CASE("className() works correctly and is constexpr") {
+  static constexpr auto struct_name = core::className<DummyStruct>();
+  static_assert(struct_name == "org::apache::nifi::minifi::test::DummyStruct");

Review Comment:
   Can we remove `getClassName` and replace its usages with `className`? It 
seems like it's doing the same thing, except that `className` can also work at 
compile-time.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to