[12/36] libcamera: yaml_parser: Add function to set a YamlObject value
diff mbox series

Message ID 20260113000808.15395-13-laurent.pinchart@ideasonboard.com
State New
Headers show
Series
  • libcamera: Global configuration file improvements
Related show

Commit Message

Laurent Pinchart Jan. 13, 2026, 12:07 a.m. UTC
Add a YamlObject::set() function to set the value of an object, with
specializations for scalar types.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/libcamera/internal/yaml_parser.h |  7 +++
 src/libcamera/yaml_parser.cpp            | 59 ++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

Patch
diff mbox series

diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h
index 7953befe11e2..c98fe003c877 100644
--- a/include/libcamera/internal/yaml_parser.h
+++ b/include/libcamera/internal/yaml_parser.h
@@ -182,6 +182,12 @@  public:
 		return get<T>().value_or(std::forward<U>(defaultValue));
 	}
 
+	template<typename T>
+	void set(T &&value)
+	{
+		return Accessor<std::remove_reference_t<T>>{}.set(*this, std::forward<T>(value));
+	}
+
 	DictAdapter asDict() const { return DictAdapter{ list_ }; }
 	ListAdapter asList() const { return ListAdapter{ list_ }; }
 
@@ -207,6 +213,7 @@  private:
 	template<typename T, typename Enable = void>
 	struct Accessor {
 		std::optional<T> get(const YamlObject &obj) const;
+		void set(YamlObject &obj, T value);
 	};
 
 	Type type_;
diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp
index 2b3723287051..9b61d3e8fc50 100644
--- a/src/libcamera/yaml_parser.cpp
+++ b/src/libcamera/yaml_parser.cpp
@@ -137,6 +137,20 @@  std::size_t YamlObject::size() const
  * \return The YamlObject value, or \a defaultValue if parsing failed
  */
 
+/**
+ * \fn template<typename T> YamlObject::set<T>(T &&value)
+ * \brief Set the value of a YamlObject
+ * \param[in] value The value
+ *
+ * This function sets the value stored in a YamlObject to \a value. The value is
+ * converted to a string in an implementation-specific way that guarantees that
+ * subsequent calls to get<T>() will return the same value.
+ *
+ * Values can only be set on YamlObject of Type::Value type or empty YamlObject.
+ * Attempting to set a value on an object of type Type::Dict or Type::List does
+ * not modify the YamlObject.
+ */
+
 #ifndef __DOXYGEN__
 
 template<>
@@ -154,6 +168,16 @@  YamlObject::Accessor<bool>::get(const YamlObject &obj) const
 	return std::nullopt;
 }
 
+template<>
+void YamlObject::Accessor<bool>::set(YamlObject &obj, bool value)
+{
+	if (obj.type_ != Type::Empty && obj.type_ != Type::Value)
+		return;
+
+	obj.type_ = Type::Value;
+	obj.value_ = value ? "true" : "false";
+}
+
 template<typename T>
 struct YamlObject::Accessor<T, std::enable_if_t<
 	std::is_same_v<int8_t, T> ||
@@ -178,6 +202,15 @@  struct YamlObject::Accessor<T, std::enable_if_t<
 
 		return value;
 	}
+
+	void set(YamlObject &obj, T value)
+	{
+		if (obj.type_ != Type::Empty && obj.type_ != Type::Value)
+			return;
+
+		obj.type_ = Type::Value;
+		obj.value_ = std::to_string(value);
+	}
 };
 
 template struct YamlObject::Accessor<int8_t>;
@@ -194,6 +227,12 @@  YamlObject::Accessor<float>::get(const YamlObject &obj) const
 	return obj.get<double>();
 }
 
+template<>
+void YamlObject::Accessor<float>::set(YamlObject &obj, float value)
+{
+	obj.set<double>(std::forward<float>(value));
+}
+
 template<>
 std::optional<double>
 YamlObject::Accessor<double>::get(const YamlObject &obj) const
@@ -215,6 +254,16 @@  YamlObject::Accessor<double>::get(const YamlObject &obj) const
 	return value;
 }
 
+template<>
+void YamlObject::Accessor<double>::set(YamlObject &obj, double value)
+{
+	if (obj.type_ != Type::Empty && obj.type_ != Type::Value)
+		return;
+
+	obj.type_ = Type::Value;
+	obj.value_ = std::to_string(value);
+}
+
 template<>
 std::optional<std::string>
 YamlObject::Accessor<std::string>::get(const YamlObject &obj) const
@@ -225,6 +274,16 @@  YamlObject::Accessor<std::string>::get(const YamlObject &obj) const
 	return obj.value_;
 }
 
+template<>
+void YamlObject::Accessor<std::string>::set(YamlObject &obj, std::string value)
+{
+	if (obj.type_ != Type::Empty && obj.type_ != Type::Value)
+		return;
+
+	obj.type_ = Type::Value;
+	obj.value_ = std::move(value);
+}
+
 template<>
 std::optional<Size>
 YamlObject::Accessor<Size>::get(const YamlObject &obj) const